# AGENTS.md
Source: https://docs.vh3.ai/agent-kits/agents-md
A drop-in context file that makes AI coding agents (Cursor, Claude Code, GitHub Copilot) fluent in the VH3 API, correct endpoints, field names, and routing logic
# AGENTS.md
`AGENTS.md` is a plain Markdown file placed at the root of your project. AI coding agents, Cursor, Claude Code, GitHub Copilot Chat, and others, read it automatically and use it as persistent context for the session. It tells the agent which endpoint to call for which question, which field names are correct, and how to behave when something goes wrong.
Drop the file once. Every agent that touches the project gets it.
**AGENTS.md is conversational context.** It guides the agent's *reasoning*, which tool to call, which parameter to use. For shaping generated *code*, pair it with [Cursor Rules](/agent-kits/cursor-rules), which apply at the code-generation level.
## The file
Copy this into `AGENTS.md` at your project root. Replace `{{YOUR_COMPANY_ID}}` and `{{YOUR_API_KEY}}` with your real credentials, or leave them as placeholders and pass them via environment variables.
Keep the section order. AI agents parse this top-to-bottom, identity and credentials first, routing second, field names third, boundaries last. Reordering degrades adherence.
```markdown AGENTS.md theme={null}
# VH3 AI: Field Service Intelligence
You have access to the VH3 AI intelligence layer for this project.
Use the tools below to answer operational questions about jobs,
engineers, sites, customers, and outcomes.
## Credentials
- Base URL: `https://api.vh3connect.io/api:kP8T1CK7`
- company_id: {{YOUR_COMPANY_ID}}
- api_key: {{YOUR_API_KEY}}
Pass both on every request. POST: in the JSON body. GET: as query params.
NEVER hardcode credentials in generated code, read from environment
variables `VH3_COMPANY_ID` and `VH3_API_KEY`.
## Tool routing
| Question pattern | Endpoint | Notes |
|---|---|---|
| "Why / root cause / what's causing" | POST /investigate | 10–17s with narrative. Use for diagnostic questions only. |
| "How many / rate / trend / top / compare" | POST /aggregate/jobs | Use `period` shorthand. Always pass `timeAxis`. |
| "Show me / list / find / get" | GET /jobs/feed | Paginated. page_size max 200. |
| "What alerts / what needs attention" | POST /sentinels/run | Returns only triggered sentinels. Empty array = all clear. |
| "Generate report / briefing / debrief" | POST /reports/generate | 10–17s with narrative. |
| "Search by meaning / similar faults" | POST /search/outcomes | Semantic similarity over outcome text. |
| Person / contact lookup | GET /search/persons | Search by name, email, or phone. |
| Weather for a job or site | POST /weather/job or POST /weather/site | |
When the question is ambiguous, default to `aggregate/jobs` first, then
offer to run `investigate` if the user wants root-cause analysis.
## Field names (CRITICAL: never invent these)
Entity IDs:
- Job: `jobId` (int), external ref: `reference` (string, e.g. "FAB303178")
- Engineer: `resourceId` (string)
- Site: `siteKey` (string)
- Customer: `contactId` (int)
- Job group: `jobGroupId` (int)
- Parent customer: name string (e.g. "Whitbread PLC")
Use camelCase for filter fields in POST bodies. EXCEPTION: legacy v1
endpoints (/search/outcomes, /sentinels/run, /connie/chat) use snake_case
(company_id, api_key). Check the OpenAPI spec when unsure:
https://api.vh3connect.io/openapi.json
Job status values: completedOk | completedWithIssues | inProgress | notStarted
Job result examples: "Job Complete" | "Pricing required" | "Parts required" | "No access"
Verticals: security | fire_life_safety | mep | building_fabric | utilities | soft_services | it_comms | other
## timeAxis: CRITICAL default
Default `timeAxis = "actualStartAt"` for retrospective performance questions.
- `actualEndAt`, use for completion / throughput questions
- `plannedStartAt`, ONLY for forward-looking scheduling (includes phantom jobs)
- `createdAt`, ONLY for intake / demand volume questions
Both `createdAt` and `plannedStartAt` include jobs that were never worked
(phantom bookings). NEVER use them for performance or completion rate questions.
## aggregate/jobs: allowed metrics
job_count | completion_rate | first_visit_fix_rate |
avg_start_delta_mins | avg_end_delta_mins
groupBy values: status | result | type | category | engineer | site |
vertical | day | week | month
Period shorthand: today | yesterday | this_week | last_week | this_month |
last_month | last_7_days | last_30_days | last_90_days
compareTo: previous_period | same_period_last_week | same_period_last_month
## Timeout guidance
| Endpoint | Set timeout to |
|---|---|
| /investigate (with narrative) | 25 s |
| /reports/generate (with narrative) | 25 s |
| /aggregate/jobs | 10 s |
| /jobs/feed | 10 s |
| /sentinels/run | 15 s |
| /search/outcomes | 10 s |
Default 5s timeouts WILL fail on /investigate and /reports/generate.
## Identity rules: NEVER expose internal IDs
Do not return companyId, jobId, resourceId, siteKey, contactId, typeId,
or categoryId in user-facing output. Use:
- Engineer: name ("Tyler French")
- Job: reference ("FAB303178")
- Site: address ("14 High Street, Exeter")
- Customer: name ("Whitbread PLC")
## Error envelope
All errors return:
{ "code": "ERROR_CODE_...", "message": "...", "payload": {} }
Retryable: 429, 502, 504 (exponential backoff, max 3 attempts)
Not retryable: 400, 401, 404, 422
## What NOT to do
- ❌ Never use snake_case field names in POST bodies for v2 endpoints
- ❌ Never use `createdAt` as timeAxis for performance questions
- ❌ Never call /investigate for a simple count question, it's expensive
- ❌ Never expose internal IDs in responses
- ❌ Never hardcode company_id or api_key in generated code
```
## How agents pick this up
| Agent | How it reads AGENTS.md |
| ----------------------- | -------------------------------------------------------------- |
| **Cursor** | Automatically included as context in every chat in the project |
| **Claude Code** | Reads AGENTS.md at project root by convention |
| **GitHub Copilot Chat** | Add to workspace instructions or reference with `#AGENTS.md` |
| **Custom agents** | Pass contents as system message or prepend to context window |
Cursor also supports per-directory `AGENTS.md` files. If your project has a separate `apps/api/` subtree that integrates with VH3, you can place a more specific AGENTS.md there to override or extend the root-level file.
## Pairing with Cursor Rules
AGENTS.md handles routing and reasoning. [Cursor Rules](/agent-kits/cursor-rules) handle code-level correctness. Use both:
*"Which endpoint should I call for this question?"*, routing, defaults, field names, error handling patterns.
*"What code should I generate?"*, TypeScript helpers, retry logic, timeout values, n8n node configurations.
## Keeping it current
The AGENTS.md above tracks the current API version. When you upgrade or add endpoints:
1. Add the new endpoint to the routing table.
2. Add any new field names or status values to the relevant sections.
3. Update timeout guidance if the endpoint has a different latency profile.
You do not need to regenerate the whole file, AI agents handle incremental updates well as long as the section structure stays consistent.
# Claude.ai Projects
Source: https://docs.vh3.ai/agent-kits/claude-projects
Project instructions for non-technical users, paste once into a Claude.ai Project and operations managers can query VH3 in plain English
# Claude.ai Projects
For ops managers, account directors, and anyone who isn't writing code: this kit turns a [Claude.ai Project](https://claude.ai) into a VH3-fluent assistant. Paste the instructions once. After that, anyone on your team can ask questions in plain English and get cited, data-backed answers.
**No code required.** This is the lowest-friction path to using VH3 from a chat interface. Built for the non-technical persona, engineers, operations managers, account managers.
## Setup
In Claude.ai, click **Projects → Create project**. Name it *"VH3 Field Service Intelligence"* (or your company name).
Open the project's **Custom instructions** panel and paste the full block below.
In the instructions, replace `{{YOUR_API_KEY}}` and `{{YOUR_COMPANY_ID}}` with your real credentials.
In the project's **Integrations** section, add the [VH3 MCP server](/agent-kits/mcp-setup) so Claude can call the API. Or, for read-only conversational use, the agent can use the [native-rag endpoint](/api-reference/connie) directly via your team's gateway.
Open a new chat in the project. Try one of the [example questions](#example-questions-to-paste-first) below.
## The project instructions
Copy the whole block. Do not edit the structure, the order of sections (identity → what you can ask → how I'll respond → boundaries) is how Claude reasons about its role.
```markdown Project instructions theme={null}
You are the field service operations assistant for our company. You have
direct access to our VH3 AI intelligence layer, which holds an enriched,
always-current picture of every job, engineer, site, customer, and outcome
in our operation.
When the user asks a question, use the VH3 tools to look up real data
from our records before answering. Cite specific job references, named
engineers, and sites in your responses. Never make up numbers.
## Credentials
- company_id: {{YOUR_COMPANY_ID}}
- api_key: {{YOUR_API_KEY}}
Pass these on every tool call automatically, the user should never have
to provide them.
## What you can answer
Operational questions like:
- "How are we performing this week vs last?"
- "Which engineers are consistently late?"
- "Why are roofing jobs failing to complete?"
- "What's the backlog for [customer]?"
- "Show me jobs at [site] over the last month"
- "What happened with job [reference]?"
- "Run the sentinels, what needs attention today?"
- "Generate today's close-of-business report"
- "Did weather affect the jobs at [site] yesterday?"
- "Which sites have recurring faults?"
- "Top 10 customers by callout volume this quarter"
## How to respond
1. **Lead with the headline.** One sentence answer at the top.
2. **Back it with data.** Cite specific job references (e.g. "FAB303178"),
engineer names ("Tyler French"), and sites ("14 High Street, Exeter").
3. **Use tables for lists.** When showing multiple jobs, engineers, or
sites, format as a markdown table.
4. **For comparisons, lead with the delta.** "Completions are up 12%
this week (218 vs 195 last week)."
5. **Flag partial periods.** If today is Wednesday and you're showing
"this week", say so, the numbers will increase.
6. **End with a next step.** Offer to drill deeper, investigate
root causes, or generate a fuller report.
## How NOT to respond
- ❌ Never expose internal database IDs (companyId, jobId, resourceId,
siteKey, contactId). Use names and references.
- ❌ Never dump raw JSON. Synthesise into prose, tables, or bullets.
- ❌ Never guess numbers if a tool call fails, tell the user the lookup
failed and offer to try a different angle.
- ❌ Never default to "createdAt" for performance questions, use
actualStartAt for real-activity questions.
## Tool selection guide
| Question pattern | Tool to call |
|---|---|
| "Why / root cause / what's causing" | investigate |
| "How many / rate / trend / top / compare" | aggregate_jobs |
| "Show me / list / get / find" | jobs_feed |
| "What alerts / what needs attention" | sentinels_run |
| "Generate report" | reports_generate |
| "Weather for job / site" | weather_for_job / weather_for_site |
| Ambiguous, could go either way | aggregate_jobs first, then offer investigate |
## Voice
You are a calm, competent operations colleague. Not a chatbot.
Plain English. No emoji. No "Great question!" preamble. Get to the
answer. Use British English spellings.
```
## Example questions to paste first
Once the project is set up, these are the questions to try first, they showcase the breadth of what's possible.
* *"Who are the top 5 engineers by first-visit fix rate this month?"*
* *"Which engineers consistently finish late on HVAC jobs?"*
* *"Compare departments on completion rate over the last 90 days."*
* *"Why are drainage jobs taking longer than planned?"*
* *"What's driving the increase in pricing-required outcomes for Whitbread sites?"*
* *"We've had three callouts at site \[address] this quarter, what's going on?"*
* *"Generate today's start-of-day briefing."*
* *"Give me the close-of-business report for yesterday."*
* *"Generate the monthly account report for our largest customer."*
* *"Run the sentinels and summarise what needs attention today."*
* *"Which sites have triggered repeat-failure alerts in the last week?"*
* *"Are there any dormant customers worth re-engaging?"*
* *"Completions this week vs last week, broken down by vertical."*
* *"Job intake today compared to yesterday."*
* *"First-visit fix rate this month vs last month by engineer."*
## What "good" looks like
Here's the kind of response you should expect once the project is set up correctly:
> **Roofing job delays are driven by three main factors: complex repairs requiring specialists, the need for structural surveys and pricing approvals, and adverse weather conditions.**
>
> Out of completed-with-issues roofing jobs in the last 90 days, **1,661** ended with "Pricing required" and **1,215** remain "Job ongoing", the majority of non-completions are diagnostic visits that couldn't resolve the issue on-site.
>
> **Key findings:**
>
> * Over 1,600 roofing jobs end at the quoting stage because damage is too extensive to fix without approval, storm damage with 50+ broken slates (FAB303318), incorrectly lapped felt needing scaffolding (J305209), or failing cob walls requiring structural surveys (FAB303178).
> * Weather is a recurring delay factor (FABQ307891 was stalled by adverse weather).
> * Multi-trade complexity adds procurement and scheduling delays.
>
> **Recommendations:**
>
> 1. Streamline the post-diagnosis pricing pipeline with pre-approved frameworks for roofing subcontractors.
> 2. Build weather contingency into roofing schedules.
> 3. Equip engineers for temporary waterproofing on first visits.
>
> *Confidence: high. Scope: completed-with-issues roofing jobs, last 90 days. Want me to drill into any of these patterns?*
Note: headline first, evidence cited with specific job refs, ranked recommendations, confidence, offered next step.
## For wider team rollout
Claude.ai Projects can be shared across your team. Everyone who joins inherits the instructions and the connected tools, no per-person setup.
Instead of pasting the API key into instructions, use the [MCP server config](/agent-kits/mcp-setup) with credentials in environment variables. Then the project instructions reference the tool, not the secret.
Add a "Local vocabulary" section to the instructions, if your team calls verticals "Trades" or "Disciplines", tell the agent.
If most questions are about one parent customer or one region, add defaults: "When no customer is specified, default to Whitbread PLC."
For a more powerful setup, pair this project with [Connie](/api-reference/connie), VH3's purpose-built conversational layer. Connie has all this routing intelligence built in, plus generative UI rendering. The Claude.ai project is for teams who prefer to stay in their existing AI chat tool.
# Claude Skills
Source: https://docs.vh3.ai/agent-kits/claude-skills
Anthropic SKILL.md template for Claude Code and MCP clients, operational routing, tool selection, and response format for the VH3 intelligence layer
# Claude Skills
[Anthropic Skills](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/skills) are Markdown files with YAML frontmatter that Claude loads when a task matches the skill description. Use this kit when you want Claude Code, Claude Desktop with skills, or another Anthropic-compatible client to answer field service operations questions with the correct VH3 MCP tools and parameters.
**Skills are triggered context.** Unlike [AGENTS.md](/agent-kits/agents-md) (always-on project context) or [Claude.ai Projects](/agent-kits/claude-projects) (paste-once project instructions), a skill activates when the user's question matches the `description` in the frontmatter. Pair with the [MCP Server](/agent-kits/mcp-setup) so the tools referenced below are available.
## Setup
Follow [MCP Server setup](/agent-kits/mcp-setup) so tools like `vh3-ai-v2:investigate` and `vh3-ai-v2:aggregate_jobs` are available to the client.
In your skills directory (e.g. `.claude/skills/vh3-ops-assistant/SKILL.md` for Claude Code), create a file named `SKILL.md`.
Copy the full block below into `SKILL.md`.
Replace `{{YOUR_COMPANY_ID}}` and `{{YOUR_API_KEY}}` with your real values from [Authentication](/authentication). Never commit live credentials to source control.
## The skill file
Keep the frontmatter `description` broad enough to catch casual operational questions, that is what triggers the skill. Do not shorten the tool-selection tables; they prevent invalid parameter names at the API.
```markdown SKILL.md theme={null}
---
name: vh3-ops-assistant
description: >
Field service operations assistant with direct access to the VH3 AI intelligence layer.
Use this skill whenever the user asks ANY operational question about jobs, engineers, sites,
customers, performance, reports, alerts, or field service data, including questions like
"how are we doing this week", "which engineers are struggling", "what happened with job X",
"run the sentinels", "generate a report", "why are jobs failing", "show me [customer]'s
backlog", "did weather affect jobs at [site]", or any question that requires looking up
real data from VH3. Trigger even for casual or loosely phrased operational questions,
if it touches jobs, engineers, sites, customers, or performance, this skill applies.
---
# VH3 Field Service Operations Assistant
You are a calm, competent field service operations colleague. You have direct access to the
VH3 AI intelligence layer, which holds an enriched, always-current picture of every job,
engineer, site, customer, and outcome in the operation.
Use the VH3 tools to look up real data before answering. Cite specific job references,
named engineers, and sites. Never make up numbers. If a tool call fails, say so and offer
a different angle, do not guess.
---
## Credentials
Pass these on **every** vh3_* tool call:
- `company_id`: `{{YOUR_COMPANY_ID}}`
- `api_key`: `{{YOUR_API_KEY}}`
---
## Tool selection
| Question pattern | Tool to call first |
|---|---|
| "Why / root cause / what's causing" | `vh3-ai-v2:investigate` |
| "How many / rate / trend / top / compare" | `vh3-ai-v2:aggregate_jobs` |
| "Show me / list / get / find" | `vh3-ai-v2:jobs_feed` |
| "What alerts / what needs attention" | `vh3-ai-v2:run_sentinels` |
| "Generate report" | `vh3-ai-v2:reports_generate` |
| "Weather for job / site" | `vh3-ai-v2:weather_for_job` |
| Broad context / open analysis | `vh3-ai-v2:investigate` with `vh3-ai-v2:jobs_feed` |
| Ambiguous, could go either way | `aggregate_jobs` first, then offer `investigate` |
### Valid report_type values (vh3-ai-v2:reports_generate)
| Value | Use case | Required params |
|---|---|---|
| `start_of_day` | Morning briefing | `date` (YYYY-MM-DD) |
| `midday` | Lunchtime check-in | `date` |
| `close_of_business` | End-of-day wrap-up | `date` |
| `day_review` | Reflective daily review | `date` |
| `start_of_week` | Weekly kickoff | `date` (any day in that week) |
| `midweek` | Mid-week pulse | `date` |
| `end_of_week` | Weekly summary | `date` |
| `account_monthly` | Customer account report | `month` (YYYY-MM) + `contact_id` |
Never use: `weekly_summary`, `monthly_summary`, `daily_summary`, `month_review`, `end_of_month`.
Omit the `sections` parameter entirely to get all sections. Never pass `{}` or `[]`.
### Valid metric values (vh3-ai-v2:aggregate_jobs)
`count` · `onTime` · `avgDuration` · `completionRate`
Never use: `firstTimeFix`, `fvf_rate`, `ftf`, `first_time_fix`, `sla`, `breach`.
If `aggregate_jobs` fails, fall back to `vh3-ai-v2:investigate` and parse outcomes manually.
### Valid preset values (vh3-ai-v2:investigate)
| Preset | Use case | Required filters |
|---|---|---|
| `context` | Broad operational context for a date range | None mandatory |
| `job_neighborhood` | Graph neighbourhood around a specific job | `jobId` |
| `customer_subgraph` | All jobs, engineers, history for a customer | `contactId` |
| `engineer_workload` | Workload for a specific engineer | `resourceId` (required) |
| `site_history` | Full job history for a site | `siteKey` |
Never use: `engineer_throughput`, `sla_breach_summary`, `site_recurring_issues`, `performance_summary`.
Do not add pre-flight validation for presets, pass them directly and let the API validate.
---
## Recommended workflows
### Weekly performance analysis
1. `vh3-ai-v2:aggregate_jobs`, `metric=count`, `metric=onTime`, `metric=completionRate`
2. `vh3-ai-v2:investigate`, `preset=context`, `date_from`/`date_to`
3. Parse `HAS_RESULT` relationships on job nodes for outcome breakdown
4. Optionally: `vh3-ai-v2:reports_generate` with `report_type=end_of_week`
### Engineer performance
1. `vh3-ai-v2:search_autocomplete`, find engineer and `resourceId`
2. `vh3-ai-v2:investigate`, `preset=engineer_workload`, `resourceId`, date range
3. `vh3-ai-v2:jobs_feed`, `resourceId` + date range for raw job list
4. `vh3-ai-v2:aggregate_jobs`, `metric=count`, `group_by=engineer` for volume comparison
### Customer / account review
1. `vh3-ai-v2:search_autocomplete`, find `contactId`
2. `vh3-ai-v2:investigate`, `preset=customer_subgraph`, `contactId`
3. `vh3-ai-v2:reports_generate`, `report_type=account_monthly`, `contact_id`, `month`
### Specific job lookup
1. `vh3-ai-v2:get_job`, job reference
2. `vh3-ai-v2:weather_for_job`, if weather context is relevant
---
## Response format
**1. Lead with the headline.** One sentence at the top.
**2. Back it with data.** Cite specific job references (e.g. "FAB303178"), engineer names
("Tyler French"), and sites ("14 High Street, Exeter").
**3. Use tables for lists.** Multiple jobs, engineers, or sites → markdown table.
**4. For comparisons, lead with the delta.** "Completions are up 12% this week (218 vs 195)."
**5. Flag partial periods.** If today is Wednesday and showing "this week", say so.
**6. End with a next step.** Offer to drill deeper, investigate root causes, or run a report.
---
## What NOT to do
- Never expose internal IDs (companyId, jobId, resourceId, siteKey, contactId), use names and references instead.
- Never dump raw JSON, synthesise into prose, tables, or bullets.
- Never guess numbers if a tool call fails, say the lookup failed and offer another approach.
- Never use "createdAt" for performance questions, use `actualStartAt` for real-activity data.
- Never use Connie (`vh3-ai-v2:connie_chat`) for data analysis or performance questions.
---
## Voice
Plain British English. No emoji. No "Great question!" preamble. Calm and direct.
Get to the answer.
```
## Skills vs other kits
| Kit | When to use |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| **Claude Skills** (this page) | Claude Code or any client that loads Anthropic-format `SKILL.md` files on matching tasks |
| [AGENTS.md](/agent-kits/agents-md) | Always-on context for coding agents in a repo |
| [Claude.ai Projects](/agent-kits/claude-projects) | Non-technical ops team in the Claude.ai web UI |
| [MCP Server](/agent-kits/mcp-setup) | Required backend, exposes the `vh3-ai-v2:*` tools this skill calls |
For production deployments, prefer MCP JWT auth from [MCP Server setup](/agent-kits/mcp-setup) over embedding API keys in the skill file. If your client supports environment-backed credentials, reference those instead of pasting secrets into `SKILL.md`.
# Cursor Rules
Source: https://docs.vh3.ai/agent-kits/cursor-rules
Drop-in .cursor/rules/ files that make Cursor's code generation VH3-aware, correct field names, proper error handling, n8n workflow conventions
# Cursor Rules
Cursor reads `.cursor/rules/*.mdc` files automatically and applies them to chats based on the rule's scope. Unlike [AGENTS.md](/agent-kits/agents-md), which is conversational context, Cursor rules apply specifically to **code generation:** they shape what Cursor *writes*, not just what it *says*.
Drop the three files below into `.cursor/rules/` and any code Cursor generates in that project will use the right parameter names, handle the right errors, and follow the VH3 API conventions.
**Use rules + AGENTS.md together.** AGENTS.md tells the agent which endpoint to call for which question. Cursor rules ensure the code it writes around those calls is correct.
## File 1: `vh3-api-domain.mdc` (always apply)
This rule gives Cursor persistent VH3 vocabulary. It applies to every chat in the project.
````markdown .cursor/rules/vh3-api-domain.mdc theme={null}
---
description: VH3 AI API domain vocabulary, schemas, and field names. Always apply.
alwaysApply: true
---
# VH3 AI: Domain Model
All code in this project integrates with the VH3 AI intelligence layer.
Use these exact names and types when generating API calls, type
definitions, or data models.
## Base URL & auth
- Base URL: `https://api.vh3connect.io/api:kP8T1CK7`
- Every request requires `company_id` (string) and `api_key` (string)
- POST: pass in JSON body. GET: pass as query params.
- NEVER hardcode credentials. Read from `VH3_COMPANY_ID` and `VH3_API_KEY`
environment variables.
## Entities
- `Job`, id: `jobId` (int), external ref: `reference` (string, e.g. "FAB303178")
- `Engineer`, id: `resourceId` (string), display: `name`
- `Site`, id: `siteKey` (string), display: `siteAddress`
- `Customer`, id: `contactId` (int), display: `name`
- `JobGroup`, id: `jobGroupId` (int), groups related visits
- `ParentCustomer`, id: name string (e.g. "Whitbread PLC")
## Job key fields
- `reference`, `jobId`, `companyId`
- `status`, completedOk, completedWithIssues, inProgress, notStarted
- `result`, "Job Complete", "Pricing required", "Parts required", "No access"
- `vertical`, security | fire_life_safety | mep | building_fabric |
utilities | soft_services | it_comms | other
- Timing: `plannedStartAt`, `actualStartAt`, `startDeltaMins`, `endDeltaMins`
- `processedOutcome`, long-form text, always truncate before display
## CRITICAL: never invent parameter names
Use exactly these names (camelCase, NOT snake_case for filter fields):
✅ `companyId` (NOT company_id in JSON bodies of v2 endpoints)
✅ `resourceId` (NOT engineer_id, resource_id, engineerId)
✅ `siteKey` (NOT site_id, site_key, siteId)
✅ `contactId` (NOT customer_id, contact_id, customerId)
✅ `typeId` (NOT type_id, jobTypeId)
⚠️ EXCEPTION: legacy v1 endpoints (e.g. /search/outcomes, /sentinels/run,
/connie/chat) use `company_id` and `api_key` (snake_case) in the body.
Check the OpenAPI spec when unsure: https://api.vh3connect.io/openapi.json
## Aggregation metrics (whitelisted)
POST /aggregate/jobs accepts only these metrics:
- `job_count`
- `completion_rate`
- `first_visit_fix_rate`
- `avg_start_delta_mins`
- `avg_end_delta_mins`
GroupBy: status, result, type, category, engineer, site, vertical,
day, week, month.
Period shorthand: today, yesterday, this_week, last_week, this_month,
last_month, last_7_days, last_30_days, last_90_days.
CompareTo: previous_period, same_period_last_week, same_period_last_month.
## timeAxis: CRITICAL default
Default `timeAxis = "actualStartAt"` for any retrospective question.
Other values: actualEndAt (completions), plannedStartAt (forward-looking
only, includes phantom jobs), createdAt (intake only), scheduledAt
(dispatching).
## Error envelope
All errors:
```
{ "code": "ERROR_CODE_...", "message": "...", "payload": {} }
```
Status codes: 400 validation, 401 unauthorised, 404 not found, 422
semantic validation, 429 rate limit, 500 server error. Retryable: 429,
502, 504. Not retryable: 400, 401, 404, 422.
## Identity in responses
Never expose `companyId`, `jobId`, `resourceId`, `siteKey`, `contactId`,
`typeId`, `categoryId` in user-facing output. Use names and references.
````
## File 2: `vh3-api-calls.mdc` (TypeScript / JavaScript / Python)
This rule applies when writing API integration code in `.ts`, `.js`, or `.py` files.
````markdown .cursor/rules/vh3-api-calls.mdc theme={null}
---
description: VH3 API call patterns, auth, timeouts, retries, error handling
globs: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.py"]
alwaysApply: false
---
# VH3 API: Code Patterns
When writing code that calls the VH3 API, follow these patterns.
## Auth: always from env
```ts
const VH3_BASE = "https://api.vh3connect.io/api:kP8T1CK7";
const VH3_COMPANY_ID = process.env.VH3_COMPANY_ID!;
const VH3_API_KEY = process.env.VH3_API_KEY!;
```
Throw a clear error if either is missing at module load, do not let
requests fail with 400 at runtime.
## Standard POST helper
```ts
async function vh3Post(path: string, body: Record): Promise {
const res = await fetch(`${VH3_BASE}${path}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
company_id: VH3_COMPANY_ID,
api_key: VH3_API_KEY,
...body,
}),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Vh3Error(res.status, err.code, err.message);
}
return res.json() as Promise;
}
```
## Timeouts
| Endpoint | Set timeout to |
|---|---|
| `/investigate` (with narrative) | 25s |
| `/reports/generate` (with narrative) | 25s |
| `/aggregate/jobs` | 10s |
| `/jobs/feed` | 10s |
| `/sentinels/run` | 15s |
| `/search/outcomes` | 10s |
The `/investigate` and `/reports/generate` endpoints with narrative have
10–17s expected latency. Do NOT set a 5s timeout.
## Retry policy
Retry on 429, 502, 504 with exponential backoff (1s, 2s, 4s, max 3 attempts).
Do NOT retry 400, 401, 404, 422, they will not succeed.
## Pagination
`/jobs/feed` is paginated. Use `page_size` (default 20, max 200) and
`page_number`. Stop when returned array length < page_size.
## Period helpers: never compute date ranges manually
For `/aggregate/jobs`, use the `period` shorthand instead of computing
startDate/endDate. The server handles ISO week boundaries, partial
periods, and timezone correctness.
✅ `{ period: "this_week", compareTo: "previous_period" }`
❌ Manually computing `startDate = new Date(...)` then passing as filter
## TypeScript types
When generating types for API responses, mark optional fields as such
(many endpoints return optional engineer/customer/site data). Use the
OpenAPI spec at `https://api.vh3connect.io/openapi.json` as the source
of truth, do not infer types from one example response.
````
## File 3: `vh3-n8n-workflows.mdc` (n8n workflows)
For projects using [n8n-as-code](/n8n-node) to build VH3 workflows.
````markdown .cursor/rules/vh3-n8n-workflows.mdc theme={null}
---
description: VH3 API patterns inside n8n workflow files
globs: ["**/*.workflow.ts"]
alwaysApply: false
---
# VH3 API: n8n Workflow Patterns
When generating n8n nodes that call the VH3 API, follow these patterns.
## Credentials, not hardcoded values
Create an n8n credential called `vh3Api` with two fields: `companyId`
and `apiKey`. Reference in nodes via `{{ $credentials.vh3Api.companyId }}`
and `{{ $credentials.vh3Api.apiKey }}`. Never put these in node parameters.
## HTTP Request node: VH3 POST pattern
```ts
@node({
name: 'Run Sentinels',
type: 'n8n-nodes-base.httpRequest',
version: 4.2,
position: [400, 200],
})
RunSentinels = {
method: 'POST',
url: 'https://api.vh3connect.io/api:kP8T1CK7/sentinels/run',
sendBody: true,
contentType: 'json',
bodyParameters: {
parameters: [
{ name: 'company_id', value: '={{ $credentials.vh3Api.companyId }}' },
{ name: 'api_key', value: '={{ $credentials.vh3Api.apiKey }}' },
],
},
options: { timeout: 15000 },
};
```
## Common patterns
| Goal | Endpoint | Schedule trigger |
|---|---|---|
| Daily morning briefing | POST /reports/generate (start_of_day) | 07:00 weekdays |
| End-of-day debrief | POST /reports/generate (close_of_business) | 18:00 weekdays |
| Sentinel sweep + Slack alert | POST /sentinels/run → Slack node | hourly or daily |
| New-job semantic context | POST /search/outcomes triggered by FMS webhook | webhook |
| Weekly account report | POST /reports/generate (account_monthly) | Monday 09:00 |
## AI Agent node: use VH3 as a tool
When wiring an AI Agent node, connect the **VH3 AI Tool** sub-node from the
community node (`n8n-nodes-vh3ai`). Tool names, parameters, and routing
hints live on the tool definitions; do not duplicate them in the system prompt.
See [n8n Agent Prompts](/agent-kits/n8n-agents) for ready-to-paste system prompts.
## NEVER
- ❌ Never hardcode `company_id` or `api_key` in workflow JSON
- ❌ Never use the HTTP Request node's "raw body" mode, use parameters
so credentials show as `={{ $credentials... }}` not plaintext
- ❌ Never set HTTP timeout < 20000ms for /investigate or /reports/generate
- ❌ Never commit a workflow with a populated credential, push will reject
````
## Installing the rules
```bash theme={null}
mkdir -p .cursor/rules
```
Copy each block above into the corresponding filename inside `.cursor/rules/`.
Cursor reads `.mdc` files on project load. Reload the window or reopen the project to pick up changes.
Ask Cursor: *"Write me a TypeScript function that calls the VH3 aggregate endpoint to get this week's completion rate by engineer."* The generated code should use `actualStartAt` as the timeAxis, read auth from env vars, and use the correct camelCase parameter names.
## How the rules interact
`vh3-api-domain.mdc` applies to every chat. Cursor always knows the entity model and field names.
`vh3-api-calls.mdc` applies only when editing implementation files. Shapes generated code.
`vh3-n8n-workflows.mdc` applies inside n8n-as-code projects. Enforces credential and timeout conventions.
AGENTS.md handles routing and reasoning. Cursor rules handle code-level correctness. Use both.
The `globs` field uses the project-relative pattern. If your integration code lives in a subdirectory (e.g. `apps/api/src/`), the patterns still match, Cursor walks the whole tree.
# MCP Server
Source: https://docs.vh3.ai/agent-kits/mcp-setup
Connect any MCP-compatible AI client, Claude Desktop, Cursor, custom agents, directly to the VH3 intelligence layer
# MCP Server
The VH3 AI MCP server exposes the full intelligence layer as [Model Context Protocol](https://modelcontextprotocol.io) tools. Any MCP-compatible client, Claude Desktop, Cursor, a custom agent, or your own toolchain, can connect directly without building middleware.
Once connected, the client gets the same tools used by the Connie assistant: `investigate`, `aggregate_jobs`, `jobs_feed`, `run_sentinels`, `reports_generate`, `search_outcomes`, and more, with all credentials and routing handled server-side via JWT authentication.
## Server details
| Property | Value |
| -------------------- | --------------------------------------------------------------------------- |
| **SSE endpoint** | `https://api.vh3connect.io/x2/mcp/UZkEeuG7/mcp/sse` |
| **Transport** | SSE (Server-Sent Events) via `mcp-remote` proxy |
| **Auth** | Bearer JWT token in `Authorization` header (obtained from `auth/mcp-token`) |
| **Protocol version** | MCP 2025-06-18 |
## Prerequisites
Claude Desktop and Cursor connect to remote MCP servers via a lightweight proxy called [`mcp-remote`](https://www.npmjs.com/package/mcp-remote). It runs automatically through `npx`, which ships with Node.js.
Download the **LTS** installer for your platform from [nodejs.org](https://nodejs.org/en/download):
* **macOS:** Download the `.pkg` installer from [nodejs.org](https://nodejs.org/en/download), open it, and click through the wizard. No terminal required.
* **Windows:** Download the `.msi` installer. Make sure **"Add to PATH"** is checked during installation (this is the default).
After installing, verify by opening a terminal (macOS: Terminal.app, Windows: Command Prompt) and running:
```bash theme={null}
node --version
npx --version
```
Both should return a version number (e.g. `v22.x.x`). If `npx` is not recognised, Node.js is either not installed or not in your system PATH — see [Troubleshooting](#troubleshooting) below.
The MCP proxy makes outbound HTTPS connections to `api.vh3connect.io` and `registry.npmjs.org` (to fetch `mcp-remote` on first use). If your organisation uses a firewall or proxy, ask your IT team to allowlist these domains.
**Why Node.js?** Claude Desktop only supports local process (stdio) MCP servers in its config file. It cannot connect to remote HTTP/SSE endpoints directly. The `mcp-remote` proxy bridges the gap — Claude Desktop launches it as a local process, and it handles the network connection to VH3. This is [the standard pattern](https://modelcontextprotocol.io/quickstart/user) recommended by the MCP specification.
## Get your MCP token
Before connecting any client, you need a long-lived MCP token (valid for 90 days).
Call the login endpoint with your email and password to obtain a standard session token:
```bash theme={null}
curl -X POST https://api.vh3connect.io/api:lBQnyyZL/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "you@company.com", "password": "your-password"}'
```
Copy the `authToken` from the response.
Call the `auth/mcp-token` endpoint using your session token:
```bash theme={null}
curl -X POST https://api.vh3connect.io/api:lBQnyyZL/auth/mcp-token \
-H "Authorization: Bearer YOUR_SESSION_TOKEN"
```
The response contains `authToken` (your 90-day MCP token) and `expires_in: 7776000`.
Save the MCP token in an environment variable. Never commit it to source control.
```bash theme={null}
export VH3_MCP_TOKEN="eyJhbGci..."
```
## Quick start: Claude Desktop
Claude Desktop connects to the VH3 MCP server via SSE using the [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) proxy. Requires [Node.js 18+](#prerequisites).
The config file location depends on your platform:
| Platform | Path |
| ----------- | ----------------------------------------------------------------- |
| **macOS** | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| **Windows** | `%APPDATA%\Claude\claude_desktop_config.json` |
You can also open it from Claude Desktop: **Settings → Developer → Edit Config**.
Create the file if it does not exist.
**macOS:**
```json claude_desktop_config.json theme={null}
{
"mcpServers": {
"vh3-ai": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.vh3connect.io/x2/mcp/UZkEeuG7/mcp/sse",
"--header",
"Authorization:${VH3_MCP_TOKEN}"
],
"env": {
"VH3_MCP_TOKEN": "Bearer YOUR_MCP_TOKEN"
}
}
}
}
```
**Windows:**
```json claude_desktop_config.json theme={null}
{
"mcpServers": {
"vh3-ai": {
"command": "cmd",
"args": [
"/c",
"npx",
"-y",
"mcp-remote",
"https://api.vh3connect.io/x2/mcp/UZkEeuG7/mcp/sse",
"--header",
"Authorization:${VH3_MCP_TOKEN}"
],
"env": {
"VH3_MCP_TOKEN": "Bearer YOUR_MCP_TOKEN"
}
}
}
}
```
Replace `YOUR_MCP_TOKEN` with the token from [Get your MCP token](#get-your-mcp-token).
Quit fully (**Cmd+Q** on macOS, **File → Quit** on Windows — closing the window is not enough) and reopen. You should see a hammer icon in the chat input. Click it to confirm the VH3 tools are listed.
Try: *"How many jobs did we complete last week, broken down by engineer?"*
Claude will call `aggregate_jobs` and return a cited answer.
**Windows users:** You must use `"command": "cmd"` with `"/c"` as the first arg. Claude Desktop spawns the command directly without a shell, so `npx` alone will fail with `spawn npx ENOENT`. Wrapping it in `cmd /c` ensures Windows resolves `npx` via the system PATH.
The auth token is placed in the `env` block rather than inline in `args`. This is the [recommended pattern](https://www.npmjs.com/package/mcp-remote) — `mcp-remote` can misparse header values containing spaces when they appear directly in the args array on Windows.
## Quick start: Cursor
Go to **Cursor Settings → MCP** and add a new server, or edit `.cursor/mcp.json` in your project root. Requires [Node.js 18+](#prerequisites).
**macOS:**
```json .cursor/mcp.json theme={null}
{
"mcpServers": {
"vh3-ai": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.vh3connect.io/x2/mcp/UZkEeuG7/mcp/sse",
"--header",
"Authorization:${VH3_MCP_TOKEN}"
],
"env": {
"VH3_MCP_TOKEN": "Bearer YOUR_MCP_TOKEN"
}
}
}
}
```
**Windows:**
```json .cursor/mcp.json theme={null}
{
"mcpServers": {
"vh3-ai": {
"command": "cmd",
"args": [
"/c",
"npx",
"-y",
"mcp-remote",
"https://api.vh3connect.io/x2/mcp/UZkEeuG7/mcp/sse",
"--header",
"Authorization:${VH3_MCP_TOKEN}"
],
"env": {
"VH3_MCP_TOKEN": "Bearer YOUR_MCP_TOKEN"
}
}
}
}
```
Replace `YOUR_MCP_TOKEN` with your token. See [Get your MCP token](#get-your-mcp-token).
Prefer environment variables over inline tokens. Set `VH3_MCP_TOKEN` in your shell profile and reference it from the config, or use [Cursor Rules](/agent-kits/cursor-rules) alongside the MCP connection to keep tokens out of config files.
## Available tools
Once connected, these tools are available in any MCP-compatible client. No `company_id` or `api_key` inputs are needed, credentials are resolved automatically from your JWT.
### FSI Intelligence
| Tool | Description | Typical latency |
| --------------------- | --------------------------------------------------------------- | --------------- |
| `connie_chat` | Conversational AI assistant trained on your company's data | 5–15 s |
| `investigate` | Deep evidence-backed investigation using graph + vector search | 10–17 s |
| `search_outcomes` | Semantic search over job outcome text | \< 2 s |
| `search_autocomplete` | Fast typeahead across jobs, contacts, engineers, sites | \< 1 s |
| `contacts_feed` | Paginated contact list with free-text search | \< 3 s |
| `contact_detail` | Full contact detail with optional stored summary | \< 3 s |
| `weather_for_job` | Weather conditions for a job's location and time | \< 2 s |
| `company_snapshot` | Company profile and FSI platform health | \< 2 s |
| `reports_generate` | Operational reports (start\_of\_day, close\_of\_business, etc.) | 10–17 s |
| `run_sentinels` | Run sentinel alert rules on demand | 3–8 s |
### Jobs
| Tool | Description | Typical latency |
| ---------------- | -------------------------------------------------------------------- | --------------- |
| `list_jobs` | Paginated job listing with filters (status, type, contact, resource) | \< 3 s |
| `get_job` | Full FSI-enriched job detail with worksheets and graph context | \< 3 s |
| `jobs_feed` | Paginated job feed (alias for list\_jobs) | \< 3 s |
| `aggregate_jobs` | KPI metrics with period comparison and group-by dimensions | \< 3 s |
| `get_fsi_job` | FSI-enriched job detail (alias for get\_job) | \< 3 s |
### Quotes & Invoices
| Tool | Description | Typical latency |
| --------------- | ------------------------------------------------------ | --------------- |
| `list_quotes` | Paginated quote listing with filters | \< 3 s |
| `get_quote` | Full quote detail with line items | \< 2 s |
| `list_invoices` | Paginated invoice listing with filters | \< 3 s |
| `get_invoice` | Full invoice detail with line items and payment status | \< 2 s |
`investigate`, `reports_generate`, and `connie_chat` have 10–17s expected latency. Some MCP clients have aggressive timeouts. If you see tool call failures on these endpoints, check your client's timeout setting and increase it to at least 25 seconds.
## Authentication
The MCP server uses JWT Bearer token authentication. Tokens are obtained via the `auth/mcp-token` endpoint (see [Get your MCP token](#get-your-mcp-token) above).
| Property | Value |
| ------------------ | -------------------------------------------------------------- |
| **Header** | `Authorization: Bearer ` |
| **Token lifetime** | 90 days |
| **Scope** | Automatically resolves your user, company, and API credentials |
The JWT encodes your user identity. All tool calls are automatically scoped to your company, no `company_id` or `api_key` parameters are needed. Cross-tenant access is impossible.
Never commit your MCP token to source control. Use environment variables and reference them from your MCP client configuration.
## Troubleshooting
### `spawn npx ENOENT` (Windows)
Claude Desktop cannot find `npx`. Two possible causes:
1. **Node.js is not installed.** Install it from [nodejs.org](https://nodejs.org/en/download) and restart Claude Desktop.
2. **Node.js is installed but not in Claude Desktop's PATH.** Use `"command": "cmd"` with `"/c"` as the first arg (see [Windows config above](#quick-start-claude-desktop)). Alternatively, use the full path to npx: `"command": "C:\\Program Files\\nodejs\\npx.cmd"`.
### `npx is not recognized` (Windows)
Same root cause as above — Node.js is not on the system PATH. Install Node.js using the `.msi` installer (not the zip), which adds it to PATH automatically. After installing, **restart Claude Desktop** (or reboot) so it picks up the new PATH.
### "Not valid MCP server configuration"
The config JSON is malformed. Common causes:
* **Trailing comma** after the last entry in an object or array.
* **Two separate JSON objects** instead of one (e.g. `mcpServers` and `preferences` in separate `{}` blocks — they must be siblings in a single root object).
* **Using `"url"` or `"headers"` keys** — Claude Desktop does not support these. Use the `command` + `mcp-remote` pattern shown above.
Paste your config into [jsonlint.com](https://jsonlint.com) to validate the JSON syntax.
### Tools don't appear after restart
* Verify you fully quit Claude Desktop (**Cmd+Q** / **File → Quit**), not just closed the window.
* Check logs: **Settings → Developer → Open Logs Folder** and look for `mcp-remote` stderr output.
* Verify your token hasn't expired (90-day lifetime). Re-run the [token exchange](#get-your-mcp-token) if needed.
* Confirm outbound HTTPS to `api.vh3connect.io` and `registry.npmjs.org` is not blocked by a firewall.
### Tool calls timeout
`investigate`, `reports_generate`, and `connie_chat` can take 10–17 seconds. Some clients have aggressive timeouts. Increase your client's tool call timeout to at least 25 seconds.
### Further reading
* [MCP Specification](https://modelcontextprotocol.io) — the protocol standard
* [MCP Debugging Guide](https://modelcontextprotocol.io/docs/tools/debugging) — official troubleshooting
* [`mcp-remote` on npm](https://www.npmjs.com/package/mcp-remote) — the SSE proxy package
* [Claude Desktop MCP Quickstart](https://modelcontextprotocol.io/quickstart/user) — Anthropic's setup guide
## Using the MCP server from custom agents
For agents built with the Anthropic SDK, OpenAI Agents SDK, or similar frameworks:
```python Python (Anthropic SDK) theme={null}
import os
import anthropic
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-4-5",
max_tokens=4096,
mcp_servers=[
{
"type": "url",
"url": "https://api.vh3connect.io/x2/mcp/UZkEeuG7/mcp/sse",
"name": "vh3-ai-v2",
"authorization_token": os.environ["VH3_MCP_TOKEN"],
}
],
messages=[{"role": "user", "content": "What needs attention today?"}],
)
```
```typescript TypeScript (SSE transport) theme={null}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
const transport = new SSEClientTransport(
new URL("https://api.vh3connect.io/x2/mcp/UZkEeuG7/mcp/sse"),
{
requestInit: {
headers: {
Authorization: `Bearer ${process.env.VH3_MCP_TOKEN!}`,
},
},
}
);
const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);
const tools = await client.listTools();
console.log(tools); // lists all 19 VH3 tools
```
## Tool selection guide for agents
When your agent receives a free-form question and needs to decide which tool to call:
| Question pattern | Tool |
| -------------------------------------------------------------- | ------------------------------------------------ |
| "why / root cause / what's causing / investigate" | `investigate` |
| "how many / rate / trend / top / compare / period over period" | `aggregate_jobs` |
| "show me / list / find / get jobs" | `list_jobs` or `jobs_feed` |
| "what needs attention / alerts / sentinels" | `run_sentinels` |
| "generate report / briefing / debrief / weekly summary" | `reports_generate` |
| "similar to / fault like / what else looks like" | `search_outcomes` |
| "find customer / contact / site" | `contacts_feed` or `search_autocomplete` |
| "quotes / pricing / quotations" | `list_quotes` or `get_quote` |
| "invoices / billing / payments" | `list_invoices` or `get_invoice` |
| Ambiguous / unclear | `aggregate_jobs` first, then offer `investigate` |
For a full system prompt you can paste directly into your agent, see the [Claude.ai Projects](/agent-kits/claude-projects) and [n8n Agent Prompts](/agent-kits/n8n-agents) kits, both include routing logic optimised for agent use.
## Pairing with AGENTS.md
If you're using the MCP server inside a Cursor or Claude Code session, pair it with the [AGENTS.md](/agent-kits/agents-md) file in your project root. The MCP server handles execution; AGENTS.md handles routing logic, field name correctness, and the rules around what IDs to expose to users.
Handles *execution*, connects the client to the actual API, manages auth, returns real data.
Handles *reasoning*, tells the agent which tool to call, which parameters to pass, and how to present results.
# n8n Agent Prompts
Source: https://docs.vh3.ai/agent-kits/n8n-agents
System prompts for n8n AI Agent workflows using the VH3 AI community node
# n8n Agent Prompts
VH3 AI is built to be extended. The intelligence layer (enriched jobs, operational memory, discovery, sentinels, reports) sits underneath Connie, your API, and native integrations. **n8n** is where you wire that layer into the rest of your stack: Slack, email, CRM, spreadsheets, scheduling, and the thousand-plus apps your team already uses.
The [verified VH3 AI community node](https://link.vh3.ai/n8n) puts field service operations and AI on the same canvas. Install it once, connect your credentials, and build deterministic workflows or LLM-powered agents without a proprietary workflow builder or a development queue.
[Check the community node pack here](https://link.vh3.ai/n8n) for the full action list, install steps, and n8n's integration overview. For installation, hosting, and templates, see the [n8n Community Node](/n8n-node) guide.
## Why n8n is the obvious extension layer
| What you get | Why it matters |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Production automation** | Scheduling, branching, retries, and observability on a platform teams already run in anger |
| **Visual + optional code** | Operations can build on the canvas; technical teams can version workflows when they need to |
| **1,000+ connectors** | Route VH3 intelligence to Gmail, Outlook, Slack, Teams, HubSpot, Xero, Google Sheets, and the rest of your stack |
| **VH3 node + AI Tool** | 150+ operations (jobs, contacts, sentinels, reports, Connie, cases, email triage) with descriptions the agent reads at runtime |
| **Included on your plan** | Full n8n automation platform from VH3 API tier upward; community node free to install |
| **Templates and managed hosting** | 100+ starter workflows, or `{your-company}.n8n.vh3.ai` with the node pre-installed |
You do not need a closed "AI workflow" product on top of VH3. n8n is the open automation layer; the community node is the bridge. Native integrations handle sync inside the platform; n8n handles **your** routing, alerts, and custom logic.
Use **deterministic** VH3 AI nodes (cron → sentinel → Slack) when the steps are fixed. Add an **AI Agent** node when the trigger is a free-form question (Slack mention, chat, webhook). Same substrate, different control surface.
## The community node in n8n
Once installed, VH3 AI appears in the node panel with triggers, actions, and an AI Tool variant for agent workflows.
A typical automation chains Outlook or Slack with VH3 ingest, classification, and job operations, then branches on status before notifying your team.
## When to use the node directly vs an AI Agent
| Use VH3 AI nodes in the workflow when... | Add an AI Agent node when... |
| ---------------------------------------------------------------------- | --------------------------------------------------------------------- |
| Steps are fixed (daily report, sentinel digest, email triage pipeline) | The user asks in natural language (Slack mention, chat, webhook body) |
| You want no LLM cost on every run | The model should choose which VH3 operation fits the question |
| You are syncing data to CRM, sheets, or storage | You are building a conversational ops assistant |
## Architecture
```
Trigger (Slack mention / webhook / schedule / chat)
↓
AI Agent node
├── Language Model (OpenAI / Anthropic / Gemini, BYOK)
├── Memory (Buffer Window, optional)
├── System Prompt ← from this page
└── VH3 AI Tool (community node)
↓
Reply or next workflow step (Slack, email, case, etc.)
```
Tool names, parameters, and when to use each operation live on the **VH3 AI Tool** sub-node. The system prompt below shapes behaviour, identity rules, and response quality. Do not duplicate parameter lists in the prompt.
## Quick setup
Self-hosted: Settings → Community Nodes → `n8n-nodes-vh3ai`. n8n Cloud: search **VH3 AI**. Or use a [managed VH3 n8n instance](/n8n-node#hosting-options). See [Check the community node pack here](https://link.vh3.ai/n8n).
API Key and Company ID from your VH3 account. See [Credentials](/n8n-node#credentials) on the n8n node page.
Add a trigger, an **AI Agent** node, your language model, and connect the **VH3 AI Tool** generated from the community node.
Copy the [system message](#the-system-prompt) into the agent's System Message field. Optionally append the [routing appendix](#optional-routing-appendix).
Use Buffer Window memory with `sessionKey` set to channel or user id so follow-ups keep context.
## The system prompt
Paste this into the **System Message** field of the AI Agent node. It contains no workflow expressions: credentials and tool wiring stay in n8n.
Copy the whole block. The section order (role → how you work → time axis → identity → response style) is intentional.
```markdown System Message theme={null}
You are the field service operations assistant for this organisation.
You have tools connected to the VH3 AI intelligence layer: an enriched,
always-current operational model of jobs, engineers, customers, places,
outcomes, and timing.
Before answering operational questions, call the appropriate tool and use
real data from the results. Never invent numbers. If a tool fails, say
the lookup failed and offer a different angle.
## How you work
Discovery first when the question is lookup or precedent-shaped.
Use search, job feed, autocomplete, or customer knowledge tools when
the user wants similar jobs, a list, or a specific record.
Synthesis when the question needs diagnosis or narrative.
Use investigate, Connie, or report generation when the user asks why,
what is causing, or wants a briefing with cited evidence. These calls
take longer; set brief expectations if needed.
Metrics and comparisons.
Use aggregation tools for how many, rate, trend, top, and period-over-
period questions. Prefer tool defaults for time axis unless the user is
clearly asking about scheduling (upcoming) or intake (demand).
## Time axis (critical)
For backward-looking performance and workload, prefer when field work
actually started or finished, not when records were created or jobs were
only planned. Planned and created timestamps include jobs that were never
worked; do not use them for performance analysis unless the user is asking
about pipeline or scheduling.
For period comparisons (this week vs last week), use the tool comparison
parameters rather than inventing date ranges. If the current period is
partial, say so before drawing firm conclusions.
## Identity and scoping
Everything is contact-centric: customers are contacts; places are addresses
under a customer. Scope by customer name, job reference, engineer name,
and date range when the user provides them.
Never show internal identifiers in replies (database IDs, linkage keys).
Use job references, engineer names, customer names, and site addresses.
## How to respond
1. Lead with the headline answer in one sentence.
2. Support with cited job references, names, and places from tool output.
3. Use tables for lists of jobs, engineers, or sites.
4. For comparisons, lead with direction and magnitude (up 12%, down 7%).
5. End with one offered next step (investigate further, run sentinels, etc.).
6. Plain English. British spellings. No filler preamble.
If confidence is low or data is thin, say what would sharpen the answer.
```
## Optional routing appendix
Paste this **below** the main system message if you want a short reminder without repeating tool parameter docs. Tool descriptions on the VH3 AI Tool node remain the source of truth.
```markdown Routing appendix theme={null}
## Tool choice (summary)
- Why / root cause / what is driving → investigate (or Connie for dialogue)
- How many / rate / trend / top / compare → aggregate jobs
- Show / list / find a job or account → job feed or search tools
- What needs attention / alerts → run sentinels
- Briefing / debrief / report → generate report
- Similar past work / precedent → semantic search on outcomes or customer sections
Follow each tool's description for parameters. Do not guess internal IDs.
```
## Testing the agent
Once wired up, try these in your trigger channel:
| Message | Expected behaviour |
| -------------------------------------------- | -------------------------------------------------------- |
| *"How many jobs did we complete last week?"* | Aggregation over completed work, with sensible time axis |
| *"Why are roofing jobs running late?"* | Investigation or diagnostic synthesis with citations |
| *"Show me job FAB303178"* | Job feed or lookup by reference |
| *"What needs attention today?"* | Sentinels |
| *"Generate today's start-of-day briefing"* | Report generation |
## Performance notes
Investigation and reports with narrative often need 20 to 25 seconds. Set the VH3 tool or workflow timeout accordingly; default short timeouts will fail on synthesis endpoints.
Use Buffer Window memory with `contextWindowLength: 10` and `sessionKey` scoped to the channel or user. Without memory, follow-ups like "drill into roofing" lose context.
Each tool call adds tokens. The VH3 AI Tool descriptions carry routing detail; keep the system prompt focused on behaviour and identity, not parameter enums.
Prefer fast tools (search, feed, sentinels) for triggers and filters; reserve investigate and narrative reports for steps that need language. See [Operational discovery](/guides/operational-discovery).
## Related
Install, credentials, hosting, and operation list.
Verified integration page and full action catalogue.
Citizen builders, substrate, and programmatic access.
Same intelligence surface for Claude Desktop and Cursor.
# n8n Node — Coding Agent Reference
Source: https://docs.vh3.ai/agent-kits/n8n-node-reference
Complete resource, operation, and pattern reference for AI assistants building VH3 AI n8n workflows
# n8n Node — Coding Agent Reference
Attach this document at the start of any AI session where you are building VH3 AI n8n workflows. It covers the node's resources, operations, routing decisions, patterns, and constraints, and works with Claude.ai, Claude Code, Cursor, or any chat session with the file attached.
* Source: [github.com/VH3DIGITAL/n8n-nodes-vh3ai](https://github.com/VH3DIGITAL/n8n-nodes-vh3ai)
* npm: [n8n-nodes-vh3ai](https://www.npmjs.com/package/n8n-nodes-vh3ai)
* Agent prompts: [/agent-kits/n8n-agents](/agent-kits/n8n-agents)
## Connecting your AI assistant to n8n
### The recommended setup: official n8n connector + this document
The **official n8n connector** (developed by n8n GmbH, available in the Claude connector directory) connects Claude to your live n8n instance. On instances running n8n **v2.18.4 or higher**, it exposes the full instance-level MCP — including workflow building, not just execution.
**What it can do** (verified on VH3-managed instances):
| Tool | Purpose |
| --------------------------------------- | ----------------------------------------------------- |
| `get_sdk_reference` | Load the n8n Workflow SDK before writing code |
| `get_suggested_nodes` | Recommended node types for a workflow pattern |
| `search_nodes` / `get_node_types` | Discover nodes and fetch exact parameter schemas |
| `list_credentials` | Find available credentials by name (secrets redacted) |
| `validate_workflow` | Pre-deploy validation of workflow code |
| `create_workflow_from_code` | Compile SDK code and save to your instance |
| `search_workflows` / `execute_workflow` | Find and run existing workflows |
**Setup (Claude.ai) — step by step:**
Switch to **Code** mode in Claude.ai. Your active connectors appear in the input bar at the bottom of the screen.
Click on the **Connectors** area, then click **Add → Browse connectors** to open the connector directory.
In the Directory, select **Connectors** and search for **n8n**. The official n8n connector by n8n GmbH will appear.
Switch to your n8n instance. Click **Settings** in the left sidebar and select **Instance-level MCP** from the menu.
Toggle Instance-level MCP on, then copy the **Server URL** shown in the Connection details panel. This is the URL you'll paste back into Claude.
**VH3-managed instances:** Your URL is `https://{your-company}.n8n.vh3.ai/mcp-server/http`. Contact VH3 support if Instance-level MCP is not yet enabled on your instance.
Back in the Claude connector directory, click the n8n connector. When the **Install n8n** dialog appears, paste your Server URL into the field and click **Continue**.
Claude will ask for permission to access your n8n instance. Click **Allow** — this grants Claude the ability to list, execute, create, and update workflows on your behalf.
The n8n connector now appears in your directory and is active in the Claude Code input bar. You can now ask Claude to build, validate, and deploy workflows directly on your instance.
**Setup (Claude Code — CLI):**
```bash theme={null}
claude mcp add --transport http n8n-mcp https:///mcp-server/http
```
Enable instance-level MCP in your n8n instance first: **Settings → Instance-level MCP**. Full tool reference: [n8n MCP tools reference](https://docs.n8n.io/advanced-ai/mcp/mcp_tools_reference/)
**VH3-managed instances:** Your n8n URL is `https://{your-company}.n8n.vh3.ai`. The `n8n-nodes-vh3ai` community node and VH3 credentials are pre-installed. Contact VH3 support if you need your MCP access token or API key.
### This reference document — the VH3 AI layer
The official n8n MCP knows n8n's built-in nodes and the Workflow SDK. It does **not** know the VH3 AI community node — its resources, operations, routing rules, or patterns. Without this document, an AI assistant will not know:
* Which resource and operation to choose for a given question (section 5)
* That `jobFeed` should be preferred over `jobs` for reads (section 3d)
* The correct `timeAxis` for performance vs intake questions (section 4)
* How `ingestEmail` status values route downstream (section 6.8)
* That custom field IDs must be fetched from the job type first (section 10)
* The exact node type name (`n8n-nodes-vh3ai.vh3Ai`) and credential type (`vh3AiApi`)
Attach this document at the start of any session where you are building VH3 AI workflows. Combined with the n8n connector, this is the complete stack.
### Optional: czlonkowski/n8n-mcp (Cursor and offline authoring)
[czlonkowski/n8n-mcp](https://github.com/czlonkowski/n8n-mcp) is a separate community MCP server. It is **not** what the official Claude n8n connector uses, and is **not** required for the build experience described above.
Consider it if you are working in **Cursor** or another editor, want stricter pre-deploy validation, or need offline node schema lookup without a live n8n connection. It uses different tool names (`n8n_create_workflow`, `get_node`, etc.) and requires a one-time install via npx or Docker.
Setup: [github.com/czlonkowski/n8n-mcp](https://github.com/czlonkowski/n8n-mcp)
### Summary
| Layer | What it provides | Required? |
| ------------------------------------------- | ----------------------------------------------------------- | -------------------------------------- |
| Official n8n connector | Build, validate, deploy, and run workflows on your instance | Yes — core setup |
| This document | VH3 AI node: resources, operations, routing, patterns | Yes — VH3 domain knowledge |
| [n8n Agent Prompts](/agent-kits/n8n-agents) | System message for AI Agent node workflows | When building conversational AI agents |
| `czlonkowski/n8n-mcp` | Offline node schema, strict validation, Cursor integration | Optional |
***
## 1. Identity
| Property | Value |
| ------------------ | ------------------------------------------------------------------------- |
| NPM package | `n8n-nodes-vh3ai` |
| Node type name | `vh3Ai` |
| Display name | `VH3 AI` |
| Credential type | `vh3AiApi` |
| `usableAsTool` | `true` — can be dropped directly into an AI Agent node as a tool sub-node |
| n8nNodesApiVersion | `1` |
***
## 2. Credential: `vh3AiApi`
Four fields are stored in the credential. Two are fixed defaults and should not be changed unless VH3 support instructs otherwise.
| Field | Internal name | Required | Default | Notes |
| ------------ | ------------- | ------------- | ---------------------------------------- | ------------------------------------------------------------------------------------ |
| API Key | `apiKey` | Yes | — | Sent as `X-API-KEY` header on every request |
| Company ID | `companyId` | Conditionally | — | Required for single-record operations (e.g. Get Job). Omit for list/feed operations. |
| Base URL | `baseUrl` | Yes | `https://api.vh3connect.io` | BigChange Web Services proxy base |
| FSI Base URL | `fsiBaseUrl` | Yes | `https://api.vh3connect.io/api:kP8T1CK7` | VH3 AI intelligence layer base |
When generating a VH3 AI node block in JSON, reference the credential as:
```json theme={null}
"credentials": {
"vh3AiApi": { "id": "", "name": "" }
}
```
***
## 3. Resource taxonomy
The node exposes **30 resources** split across three internal API layers. This split is invisible in the UI but critical for understanding timeout, latency, and data freshness expectations.
### 3a. BigChange data resources (CRUD)
These map directly to the BigChange field-service platform. Operations are typically fast (\<2 s). The resource values are used in `$parameter["resource"]`.
| Display name | `resource` value | What it covers |
| ------------------------------- | -------------------- | ------------------------------------------------------------------------ |
| Job (BigChange) | `jobs` | CRUD, schedule, start, set result, cancel, manage stock constraints |
| Contact (BigChange) | `contacts` | Companies and sites — create, read, update, delete |
| Resource / Engineer (BigChange) | `resources` | Engineers/technicians and their groups |
| Job Type (BigChange) | `jobTypes` | Job type templates (installation/repair/maintenance schemas) |
| Vehicle (BigChange) | `vehicles` | Fleet vehicles — read/create/update records and groups |
| Worksheet (BigChange) | `worksheets` | Mobile worksheet definitions, questions, and submitted answers |
| Worksheet Group (BigChange) | `worksheetGroups` | Folders that organise worksheet definitions |
| Invoice (BigChange) | `invoices` | Sales invoices and line items |
| Note (BigChange) | `notes` | Notes/tasks/updates on jobs, contacts, and persons |
| Person (BigChange) | `persons` | Individual people attached to a contact (site contacts, consent history) |
| Job Group (BigChange) | `jobGroups` | Linked sets of jobs (multi-visit projects) |
| Stock (BigChange) | `stock` | Product categories, stock details, items, movements, suppliers |
| Reference Data (BigChange) | `referenceData` | Department codes, nominal (accounting) codes |
| Quote (BigChange) | `quotes` | Sales quotes and line items |
| Sales Opportunity (BigChange) | `salesOpportunities` | CRM pipeline — read, edit, line items, probabilities, stages |
| Purchase Order (BigChange) | `purchaseOrders` | Purchase orders and line items |
### 3b. Web Services resources (BigChange driver API)
Thin proxy over the BigChange Web Services layer. Responses use different envelope shapes (`result` array, not `data`).
| Display name | `resource` value | What it covers |
| ------------------------- | ---------------- | --------------------------------------------------- |
| Attachment (Web Services) | `wsAttachments` | Retrieve/list attachments for BigChange entities |
| Report (Web Services) | `wsReports` | Driver/vehicle performance and infringement reports |
| Tracking (Web Services) | `wsTracking` | GPS journeys, live positions, odometer readings |
### 3c. VH3 AI intelligence resources
These call the FSI intelligence layer. They are **slower** (2–25 s depending on operation) and consume LLM tokens for synthesis operations.
| Display name | `resource` value | Latency tier | What it covers |
| ----------------------- | ---------------- | --------------- | ------------------------------------------------------------------ |
| Job Feed (VH3 AI) | `jobFeed` | Fast (\< 3 s) | Enriched, paginated job feed with aggregation and analytics |
| Search (VH3 AI) | `search` | Fast (\< 3 s) | Semantic and outcome search, autocomplete, customer knowledge base |
| Sentinel (VH3 AI) | `sentinel` | Medium (3–8 s) | Proactive monitoring checks |
| Pulse (VH3 AI) | `pulse` | Fast | Cached business-health dashboard snapshot |
| Email (VH3 AI) | `email` | Fast–Medium | Email triage: classify, ingest, batch classify, list rules |
| Briefing (VH3 AI) | `briefing` | Medium (5–10 s) | Pre-visit intelligence briefing + call script for an engineer |
| Case (VH3 AI) | `cases` | Fast | Case management: create, update, transition, comment, link items |
| Connie (VH3 AI) | `connie` | Medium (5–15 s) | Conversational AI assistant: chat, sessions, history search |
| Report (VH3 AI) | `reports` | Slow (10–25 s) | Operational reports (daily, weekly, monthly) with narrative |
| Investigate (VH3 AI) | `investigate` | Slow (10–25 s) | Multi-step hybrid vector + graph investigation |
| Account Report (VH3 AI) | `accountReport` | Slow (10–25 s) | Monthly account review across full parent-child hierarchy |
| Intelligence (VH3 AI) | `intelligence` | Medium | Job type profiling — list, get, generate intelligence profiles |
| Weather (VH3 AI) | `weather` | Fast | Weather for jobs, sites, forecasts, historical lookups |
| User (VH3 AI) | `users` | Fast | User management — list, invite, update role, delete |
### 3d. FSI-first principle
**When both a BigChange resource and a VH3 AI intelligence resource can answer the same question, prefer the intelligence layer.**
The FSI layer ingests and enriches all job data continuously. For read operations — job feeds, aggregations, search, analysis, monitoring — it is faster (often cached), returns richer data, and avoids unnecessary load on the BigChange API.
| Question | Prefer | Reason |
| ------------------------ | ------------------------------------------ | -------------------------------------- |
| List or search jobs | `jobFeed` (VH3 AI) over `jobs` (BigChange) | Enriched, cached, supports aggregation |
| What needs attention? | `sentinel` (VH3 AI) | Pre-computed, no extra API calls |
| Business health snapshot | `pulse` (VH3 AI) | Cached dashboard, single call |
| Find a customer by name | `search → autocomplete` (VH3 AI) | Fuzzy match, no ID required |
| Historical job analysis | `jobFeed → aggregateJobs` (VH3 AI) | Built-in metrics, period comparison |
The intelligence layer does not write to BigChange. It is read-only for operational intelligence. To create or modify records — jobs, contacts, invoices, notes — use the BigChange CRUD resources (section 3a).
***
## 4. The time axis — critical for data quality
Several Job Feed and Aggregate Jobs operations accept a `dateField` or `timeAxis` parameter. Choosing the wrong axis produces misleading results.
### Available timestamp fields
| Value | What it represents | Use when... |
| ---------------- | -------------------------------------------- | ------------------------------------------------------- |
| `actualStartAt` | When the engineer physically began the job | Measuring real performance, throughput, productivity |
| `actualEndAt` | When the engineer finished | Measuring duration, closure rates, end-of-day analysis |
| `createdAt` | When the job record was created in BigChange | Measuring intake volume, demand pipeline analysis |
| `plannedStartAt` | When the job was scheduled to start | Measuring scheduling accuracy, schedule adherence drift |
| `plannedEndAt` | When the job was scheduled to finish | — |
| `scheduledAt` | When the scheduling decision was made | — |
### Decision rules
**Default to `actualStartAt`** for any performance or workload question. It reflects real field activity and excludes jobs that were planned but never worked.
```
Question type → Recommended time axis
─────────────────────────────────── ────────────────────────
How many jobs did we complete? actualStartAt / actualEndAt
What's our first-visit fix rate? actualStartAt
How many jobs came in this week? createdAt
Are engineers on time? plannedStartAt → actualStartAt delta
What's in the schedule for today? plannedStartAt
How long do jobs take? actualStartAt → actualEndAt delta
```
`createdAt` includes jobs that were planned but never attended. Do not use it for performance analysis unless the user is explicitly asking about intake volume or pipeline.
**Partial periods**: When the current period (e.g. `this_week`) is still in progress, say so before drawing conclusions. The `compareTo` parameter (`previous_period`, `same_period_last_week`, `same_period_last_month`) handles apples-to-apples comparison automatically — prefer it over inventing date ranges.
***
## 5. Routing guide — which resource and operation to use
Use this table when the user's intent is expressed in natural language, to select the right VH3 AI node operation.
| User intent | Resource | Operation |
| ---------------------------------------------------- | --------------- | -------------------------------------------------------------- |
| "How many jobs did we complete last week?" | `jobFeed` | `aggregateJobs` — metric: `job_count`, timeAxis: `actualEndAt` |
| "What's our first-visit fix rate?" | `jobFeed` | `aggregateJobs` — metric: `first_visit_fix_rate` |
| "Show me jobs for customer X" | `jobFeed` | `listJobFeed` — filter: `contactId` |
| "Show me all jobs for an account including children" | `jobFeed` | `listAccountJobFeed` |
| "Get the detail for job FAB303178" | `jobFeed` | `getEnrichedJob` |
| "Find jobs like this one / similar past work" | `search` | `searchOutcomes` or `searchIntake` |
| "What do we know about this customer?" | `search` | `getSummaryByContact` or `searchSummarySections` |
| "Find a customer / engineer / site" | `search` | `autocomplete` |
| "What needs attention today?" | `sentinel` | `runSentinels` (sentinelId: `all`) |
| "Is there a pattern of problems at a site?" | `sentinel` | `runSentinels` — `new_problem_site` or `site_deterioration` |
| "Why are roofing jobs running late?" | `investigate` | `runInvestigation` |
| "What is causing repeat failures?" | `investigate` | `runInvestigation` |
| "Generate today's start-of-day briefing" | `reports` | `generateReport` — reportType: `start_of_day` |
| "End of week summary" | `reports` | `generateReport` — reportType: `end_of_week` |
| "Monthly account review for client X" | `accountReport` | `generateAccountReport` |
| "Brief the engineer before they visit" | `briefing` | `generateBriefing` |
| "Classify this incoming email" | `email` | `classifyEmail` or `batchClassifyEmail` |
| "Extract job data from this FM portal email" | `email` | `ingestEmail` |
| "What's our current business health?" | `pulse` | `getPulse` |
| "Ask Connie about..." | `connie` | `connieChat` |
| "Create a case for this incident" | `cases` | `createCase` |
| "Create / update a job" | `jobs` | `create` / `update` |
| "Create / update a contact" | `contacts` | `create` / `update` |
| "What's the weather for this job?" | `weather` | `getWeatherForJob` |
| "Create jobs from FM portal emails" | `email` | `ingestEmail` — route downstream on returned `status` field |
***
## 6. Per-resource operation reference
### 6.1 Job Feed (`jobFeed`)
| Operation | Key inputs | Notes |
| -------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `listJobFeed` | `status` (multi), `dateField`, `dateFrom`, `dateTo`, `contactId`, `resourceId`, `typeId` | Default `dateField`: `createdAt`. Add `simplify: true` to strip nulls. |
| `listAccountJobFeed` | `contactId` (required — any in hierarchy) | Traverses full parent-child account tree automatically |
| `aggregateJobs` | `metric`, `period`, `timeAxis`, `groupBy`, `compareTo` | Use `compareTo` for period-over-period. `groupBy` options: `status`, `result`, `typeId`, `categoryId`, `resourceId`, `siteKey`, `vertical`, `day`, `week`, `month` |
| `getEnrichedJob` | `jobId` (required), `includeWorksheets` | Returns AI enrichment: vertical, sentiment, key phrases |
**Aggregate metrics**: `job_count`, `completion_rate`, `first_visit_fix_rate`, `avg_start_delta_mins`, `avg_end_delta_mins`.
**Period presets**: `today`, `yesterday`, `this_week`, `last_week`, `this_month`, `last_month`, `last_7_days`, `last_30_days`, `last_90_days`. Override with `startDate`/`endDate` for custom ranges.
### 6.2 Search (`search`)
| Operation | Key inputs | Notes |
| ----------------------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `autocomplete` | `query`, `typeFilter` (multi: `customer`, `engineer`, `job`, `person`, `site`) | Fast fuzzy lookup across all entity types |
| `searchOutcomes` | `queryText`, `contactId`, `resourceId`, `typeId`, `maxAgeMonths` | Semantic search on job diagnostic summaries |
| `searchIntake` | `queryText`, `contactId`, `resourceId`, `typeId` | Semantic search with knowledge graph enrichment |
| `searchIntakeBasic` | `queryText` | Same as above, without graph enrichment (faster) |
| `searchSummarySections` | `query`, `contactId`, `sectionKey` | Search the CustomerSummary knowledge base. Section keys: `customer_overview`, `job_history_patterns`, `operational_performance`, `risk_opportunity`, `systems_equipment`, `communication_summary`, `key_analyses` |
| `getSummaryByContact` | `contactId`, `fullReport` | Retrieves all stored CustomerSummary sections. Set `fullReport: true` for assembled markdown. |
Date filtering on semantic search operations is applied **client-side** after the API responds. Set `maxAgeMonths` to limit result age.
### 6.3 Sentinel (`sentinel`)
| Operation | Key inputs | Notes |
| ---------------------- | ----------------------------- | ------------------------------------------------------------------ |
| `runSentinels` | `sentinelId` (default: `all`) | Returns only triggered alerts. Use `all` for a full check. |
| `getSentinelResults` | — | Returns cached results from the last run (fast, no re-computation) |
| `listSentinelRegistry` | — | Lists all sentinel definitions with thresholds and schedules |
**Available sentinels**: `carryover_accumulation`, `customer_noncomplete_anomaly`, `customer_risk_escalation`, `data_quality_alert`, `engineer_performance_slip`, `fvf_rate_drop`, `new_problem_site`, `repeat_failure_escalation`, `scheduling_accuracy_drift`, `site_deterioration`, `sla_breach_cluster`, `workload_imbalance`.
For scheduled automations, use `getSentinelResults` (cached, instant) rather than `runSentinels` (re-computes) to avoid latency in time-sensitive triggers.
### 6.4 Report (`reports`)
| Operation | Key inputs | Notes |
| -------------------- | ---------------------------------------------------- | ----------------------------------------------------- |
| `generateReport` | `reportType`, `date`, `includeNarrative`, `sections` | Narrative adds 2–5 s. Omit `sections` to include all. |
| `listReportSections` | — | Discover section IDs for selective report generation |
**Report types**: `start_of_day`, `midday`, `close_of_business`, `day_review`, `start_of_week`, `midweek`, `end_of_week`.
Set workflow/node timeout to ≥ 30 s for narrative reports.
### 6.5 Investigate (`investigate`)
| Operation | Key inputs | Notes |
| ------------------ | ------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
| `runInvestigation` | `question` (free text), `maxEvidenceItems` | Multi-step hybrid search across the intelligence layer. Expensive — 10–25 s. Do not use in polling loops. |
### 6.6 Case (`cases`)
| Operation | Notes |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `createCase` | `title` + `caseType` required. Types: `audit`, `case_study`, `compliance`, `incident`, `investigation`, `project_review` |
| `listCases` | Filter by `status`, `type`, `priority`, `ownerId` |
| `searchCases` | Full-text search across title and description |
| `getCase` | Returns participants, items, latest activity |
| `updateCase` | Patch — only provided fields change |
| `transitionCase` | Lifecycle-validated status changes. Statuses: `draft` → `open` → `in_progress` → `under_review` → `resolved` → `closed` / `archived` |
| `addComment` | Adds to activity timeline |
| `addCaseItem` | Links a job, customer, site, engineer, job group, note, or document |
| `listCasesForItem` | Reverse lookup — find all cases referencing a specific record |
### 6.7 Connie (`connie`)
| Operation | Key inputs | Notes |
| -------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `connieChat` | `message`, `sessionId` (optional), `contactId`, `userId` | Pass `sessionId` to continue an existing conversation. Set `experimentalMode: true` for the experimental pipeline. |
| `listSessions` | `userId`, `contactId` | — |
| `connieGetSessionMessages` | `sessionId` | — |
| `connieSearchHistory` | `query`, `userId`, `contactId` | — |
For AI Agent workflows, use `connieChat` with `sessionKey`-scoped `sessionId` so follow-up messages retain context.
### 6.8 Email (`email`)
| Operation | Notes |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `classifyEmail` | `subject` + `emailBody` + `senderAddress` required. Supports attachment via URL or binary data. |
| `batchClassifyEmail` | JSON array of up to 50 email objects. Portal/pre-filter hits are instant; novel emails consume LLM tokens. |
| `ingestEmail` | Extracts structured job data from FM portal emails. Returns resolved entities and a `status` field. Always switch on `status` downstream. |
| `listTriageCategories` | Returns active categories with priority, destination, and prompt rules. |
| `listTaxonomyRules` | Filter by `phase`: `pre_classify` (noise filters) or `post_classify` (routing decisions). |
**`ingestEmail` status values** — every implementation must route on this field:
| Status | Meaning |
| --------------- | ------------------------------------------------------- |
| `Create` | Entities resolved, confident — proceed to job creation |
| `Review` | Ambiguity or missing data — route to human review queue |
| `Unprocessable` | Email could not be parsed as a portal job email |
| `Rejected` | Matched a noise or exclusion rule — discard silently |
**PDF vs HTML input**: Many FM portals send job orders as PDF attachments rather than HTML body. The `ingestEmail` operation accepts plain text (`emailText`) — it does not process binary PDFs directly. For PDF-based portals, extract the text first using n8n's **Extract From File** node before passing it to `ingestEmail`. Build your workflow to switch on whether the email has a PDF attachment and handle both paths feeding the same `ingestEmail` node.
### 6.9 Briefing (`briefing`)
| Operation | Key inputs | Notes |
| ------------------ | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `generateBriefing` | `jobId` + `contactId` required | Generates structured pre-visit briefing + call script. Use `jobPayload` (JSON) if the job was created very recently and may not yet be indexed in the intelligence layer. |
### 6.10 Account Report (`accountReport`)
| Operation | Key inputs | Notes |
| ----------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `generateAccountReport` | `contactId` required | Pass any contact in the account hierarchy — the report resolves the full tree. `month` in `YYYY-MM` format, defaults to previous calendar month. |
### 6.11 Pulse (`pulse`)
| Operation | Notes |
| ---------- | ------------------------------------------------------------------------------------------ |
| `getPulse` | No inputs. Returns cached snapshot of pipeline, performance, workforce, and asset metrics. |
### 6.12 Intelligence (`intelligence`)
| Operation | Key inputs | Notes |
| ------------------ | -------------------------------- | -------------------------------------------------------- |
| `listProfiles` | `profiledOnly` (default: `true`) | Filter to only types with a generated profile. |
| `getProfile` | `typeId` | Gets the intelligence profile for a specific job type. |
| `generateProfiles` | `typeIds` (JSON array), `scope` | Regenerate profiles — use sparingly, runs in background. |
### 6.13 Weather (`weather`)
| Operation | Key inputs | Notes |
| ------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------- |
| `getWeatherForJob` | `jobId` | Fastest — resolves location from the job record automatically |
| `getWeatherForSite` | `siteKey`, optional `startDate`/`endDate` | Current or historical conditions by date range |
| `getForecast` | `latitude`, `longitude`, optional `startHour`/`endHour`/`timezone` | Point forecast for a raw coordinate |
| `getHistorical` | `latitude`, `longitude`, optional `startDate`/`endDate`/`timezone` | Historical conditions for a raw coordinate |
### 6.14 Users (`users`)
| Operation | Key inputs | Notes |
| ---------------- | --------------------------------------------- | ---------------------------------------- |
| `listUsers` | — | Returns active users only |
| `listInvites` | — | Returns pending (unaccepted) invitations |
| `inviteUser` | `email`, `role`, `companyName`, `inviterName` | Roles: `admin`, `manager`, `user` |
| `updateUserRole` | `userId`, `role` | — |
| `deleteUser` | `userId` | Soft-delete (archive) — not permanent |
***
## 7. BigChange CRUD resources — operation summary
All BigChange resources follow a consistent pattern. Key operations per resource:
### Jobs (`jobs`)
`create`, `update`, `get`, `getAll`, `delete`, `schedule`, `unschedule`, `start`, `setResult`, `cancel`, `addStock`, `deleteStock`, `updateStockQty`, `addWaypoint`, `deleteWaypoint`, `addRecurrence`
### Contacts (`contacts`)
`create`, `update`, `get`, `getAll`, `getByRef`, `delete`, `getGroups`
### Resources/Engineers (`resources`)
`get`, `getAll`, `getGroups`
### Vehicles (`vehicles`)
`get`, `getAll`, `create`, `update`, `getGroups`
### Invoices (`invoices`)
`get`, `getAll`, `create`, `addLine`, `markSent`, `markPaid`, `cancel`
### Notes (`notes`)
`create`, `update`, `get`, `getAll`, `delete`
### Persons (`persons`)
`create`, `update`, `get`, `getAll`, `delete`, `getConsentHistory`
### Quotes (`quotes`)
`get`, `getAll`, `create`, `update`, `addLine`, `markSent`, `markAccepted`, `markRejected`
### Sales Opportunities (`salesOpportunities`)
`get`, `getAll`, `update`, `addLine`, `deleteLine`, `listProbabilities`, `listStages`
### Purchase Orders (`purchaseOrders`)
`get`, `getAll`, `create`, `update`, `addLine`, `listSeries`
### Job Groups (`jobGroups`)
`get`, `getAll`, `getStatusHistory`
### Stock (`stock`)
`getCategories`, `getDetails`, `getItems`, `getMovements`, `getSuppliers`
### Reference Data (`referenceData`)
`getDepartmentCodes`, `getNominalCodes`
### Worksheets (`worksheets`)
`get`, `getAll`, `getQuestions`, `getAnswers`
### Worksheet Groups (`worksheetGroups`)
`get`, `getAll`
### Job Types (`jobTypes`)
`getAll`
***
## 8. Using the node as an AI Tool sub-node
Because `usableAsTool: true` is set, the node can be attached directly to an AI Agent node as a tool. The agent reads each operation's `description` field at runtime to decide which to call.
### Architecture for an agent workflow
```
Trigger (Slack / Webhook / Schedule / Chat)
↓
AI Agent node
├── Language model (OpenAI / Anthropic / Gemini, BYOK)
├── Memory (Buffer Window — sessionKey scoped to channel/user)
├── System Prompt (see /agent-kits/n8n-agents)
└── VH3 AI Tool (community node, all operations)
↓
Reply / next workflow step
```
### Key agent configuration notes
1. **System prompt**: Copy the system message from [/agent-kits/n8n-agents](/agent-kits/n8n-agents). It encodes the time-axis rules, identity scoping, and response format. Do not re-describe parameter enums in the system prompt — they live in the tool descriptions already.
2. **Memory**: Use Buffer Window with `contextWindowLength: 10`. Set `sessionKey` to the channel ID or user ID so follow-up queries retain context.
3. **Timeouts**: Set the VH3 AI Tool timeout to ≥ 30 s. Investigation and narrative reports regularly take 20–25 s; default short timeouts will fail silently.
4. **Token cost**: Each tool call adds tokens. Prefer fast operations (`search`, `jobFeed`, `sentinel`) in high-frequency triggers. Reserve `investigate` and `reports` for steps that genuinely need language synthesis.
### Combining the VH3 AI Tool with other LangChain sub-nodes
Complex ingestion workflows often pair the VH3 AI Tool with other LangChain nodes in the same agent or as adjacent steps. A common pattern is using the **Information Extractor** node (with a lightweight model such as Gemini Flash) to extract typed custom field values from unstructured email or document text — using the custom field schema fetched from Job Types at runtime to build the extraction prompt. This keeps field extraction data-driven rather than hardcoded to a specific job type, and handles schema changes without workflow edits. See Pattern F in section 9.
### When to use deterministic nodes vs. an AI Agent
| Use VH3 AI nodes directly (deterministic) | Add an AI Agent node |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Steps are fixed (daily report, sentinel digest, email triage pipeline) | Trigger is a free-form question (Slack mention, webhook body, chat) |
| No LLM cost desired on every run | The model should choose which VH3 operation fits the question |
| Syncing data to CRM, spreadsheets, or storage | Building a conversational ops assistant |
| Scheduled automations | Natural language queries against operational data |
***
## 9. Workflow patterns
### Pattern A: Daily sentinel digest to Slack
```
Schedule trigger (07:00)
→ VH3 AI: Sentinel — Run Sentinels (all)
→ IF node: triggered alerts > 0
→ Slack: post formatted alert list
→ [else] Slack: post "All clear"
```
### Pattern B: Email triage pipeline
```
Microsoft Outlook trigger (new email)
→ VH3 AI: Email — Classify Email
→ Switch node (on classification)
→ "new_job": VH3 AI: Job — Create + Slack notify
→ "update": VH3 AI: Job — Update
→ "noise": [no action]
```
### Pattern C: Enriched job briefing on job creation
```
Webhook trigger (BigChange job-created event)
→ VH3 AI: Briefing — Generate Briefing (jobId, contactId)
→ Slack / SMS: send briefing to assigned engineer
```
### Pattern D: Monthly account report loop
```
Schedule trigger (1st of month, 08:00)
→ VH3 AI: Contact — Get All (filter: account contacts)
→ Loop Over Items
→ VH3 AI: Account Report — Generate Account Report
→ Email: send report to account manager
```
### Pattern E: Conversational ops assistant (AI Agent)
```
Slack trigger (app mention)
→ AI Agent
├── OpenAI GPT-4o
├── Buffer Window memory (sessionKey: channelId)
├── System prompt from /agent-kits/n8n-agents
└── VH3 AI Tool (all operations)
→ Slack: reply in thread
```
### Pattern F: FM portal email → job creation with custom field extraction
This is the core portal ingestion pattern. The key non-obvious steps are the PDF/HTML split, the Information Extractor for custom fields, and the Wait + verify step that handles indexing lag between BigChange creation and FSI visibility.
```
Outlook trigger (new email)
→ Set node (centralised config: job type IDs, default contact, etc.)
→ Switch: has PDF attachment?
→ [PDF] Get Binary Attachment → Extract From File (PDF→text)
→ [HTML] extract body text
→ VH3 AI: Email — Ingest Email (emailText + preferredTypeIds from config)
→ Switch: ingestEmail.status
→ "Create":
→ VH3 AI: Job Type — Get All (fetch schema for matched type)
→ Information Extractor LLM node (Gemini Flash)
prompt built from job type custom field definitions + email text
→ Code: assemble job payload with extracted custom field values
→ VH3 AI: Jobs — Create
→ Wait (30 s — allow FSI indexing)
→ VH3 AI: Job Feed — Get Enriched Job (lightweight verify)
→ Reply email: confirmation with job reference
→ "Review": send to human approval queue (email / Slack)
→ "Unprocessable" / "Rejected": log to spreadsheet / case and exit
```
Any workflow with more than two configurable values — type IDs, contact IDs, email addresses, Slack channels — should centralise them in a Set node at the start. This makes the workflow easy to adapt per tenant without hunting through individual node parameters.
### Pattern G: Bulk tabular import (CSV / XLSX → jobs)
Converting spreadsheet rows into synthetic portal email bodies lets the same `ingestEmail` pipeline handle both live emails and bulk imports without duplicating job creation logic.
```
Form trigger (file upload — xlsx or csv)
→ Switch: file format
→ Extract From File (xlsx) / Extract From File (csv)
→ Code: build synthetic portal email body from each row
→ Split in Batches (configurable batch size, e.g. 5)
→ VH3 AI: Email — Ingest Email (per row)
→ Switch: status → "Create" path (same as Pattern F) / record result
→ [loop continues]
→ Summary email: total created / review / failed
```
***
## 10. Important constraints
### General
* **Never expose internal IDs** in agent replies. Use job references, engineer names, customer names, and site addresses.
* **`companyId` in credentials** is required for single-record Get operations on BigChange resources. It is not required for VH3 AI intelligence operations.
* **`simplify: true`** (where available) strips null, empty string, and empty array fields from responses — recommended when passing data downstream.
* **`returnAll: true`** on list operations uses automatic pagination. Only use it when you genuinely need the full dataset; large tenants can have thousands of jobs.
* **Batch email classification** (`batchClassifyEmail`) is significantly more efficient than calling `classifyEmail` in a loop. Use it whenever you have multiple emails to process in the same step.
* **Binary data in workflows.** Any workflow that handles file attachments (PDFs, spreadsheets, images) should have **Binary mode** set to **Filesystem** in the workflow settings. Without this, binary payloads are stored inline with execution records, which causes memory pressure and can silently fail on large files. Set this before building any attachment-handling or import workflow.
### Destructive actions — confirm before generating
Any operation that **creates, updates, deletes, cancels, or transitions** a BigChange record is irreversible or difficult to undo. Before generating a workflow that includes these operations:
1. **Confirm intent explicitly** with the user — do not infer that a write is needed from context alone.
2. **Check for existing records** before creating. Duplicate jobs, contacts, or invoices are a common source of data quality problems.
3. **Scope updates narrowly** — patch only the fields the user specified. Do not reset or overwrite fields that were not mentioned.
4. If you are unsure about the correct approach for a write operation, say so and ask the user rather than proceeding on an assumption.
### Custom fields on jobs — fetch the job type first
BigChange jobs support custom fields whose schema is defined per job type. The available fields, their IDs, and their value types vary by tenant configuration.
Before constructing a Create Job or Update Job payload that includes custom fields, always fetch the job type first using `Job Type (BigChange) → getAll` and inspect the returned custom field definitions. Do not guess field IDs or types — they are not portable between job types or tenants.
The same principle applies to other entities with custom field support (contacts, resources). If you are unsure whether custom fields are involved, ask.
### Polling frequency
* Avoid high-frequency polling loops with expensive operations. `investigate`, `generateReport`, and `generateBriefing` are not suitable for loops that run more than once per trigger event.
* For sentinel monitoring, prefer `getSentinelResults` (cached, returns pre-computed results instantly) over `runSentinels` (re-computes) in any schedule that runs more than once or twice per day.
* Where BigChange supports webhooks or event-based triggers, use them in preference to polling on a tight schedule.
* If a workflow needs to wait for a job status to change, use a wait/delay node with a reasonable interval rather than a tight loop.
### Relative timestamps in expressions
Hardcoded dates make workflows brittle. Use n8n's Luxon-based `$now` expression for any date that should be calculated at runtime.
```
Today (ISO): {{ $now.toISO() }}
Start of today: {{ $now.startOf('day').toISO() }}
7 days ago: {{ $now.minus({ days: 7 }).toISO() }}
Start of this week: {{ $now.startOf('week').toISO() }}
Start of last month: {{ $now.minus({ months: 1 }).startOf('month').toISO() }}
End of last month: {{ $now.minus({ months: 1 }).endOf('month').toISO() }}
YYYY-MM (for reports): {{ $now.minus({ months: 1 }).toFormat('yyyy-MM') }}
```
Use these patterns when populating `dateFrom`, `dateTo`, `startDate`, `endDate`, and `month` fields. Never hardcode a date string in a workflow intended to run on a schedule.
***
## 11. Workflow authoring practice
### Sticky notes
Use n8n's **Sticky Note** node liberally on the canvas. Add a sticky note:
* At the top of every workflow describing its purpose, trigger conditions, and any VH3 or BigChange-specific context a future editor will need.
* Beside any node that calls a write operation, explaining why the write is necessary and what happens if it fails.
* Wherever a parameter value is non-obvious (e.g. a specific contact ID, hardcoded job type, or calculated expression) to explain the reasoning.
* At branch points (Switch, IF) to document the routing logic in plain English.
Sticky notes have no execution cost and make a significant difference when workflows are revisited weeks later or handed to another developer.
### Capturing user preferences and recurring patterns
When building workflows for a specific tenant or user, notice patterns that emerge in how they describe their work:
* Preferred job statuses, result values, or engineer groupings they always filter by.
* Specific customers or sites they monitor closely.
* Report cadences and delivery channels they rely on.
* Naming conventions for workflows, notes, and cases.
Where the same preference appears more than once, consider surfacing it as a workflow-level variable or a dedicated config node at the top of the workflow rather than embedding it in multiple node parameters. This makes the workflow easier to adapt without hunting through individual nodes.
If you observe a pattern that suggests a repeating automation opportunity (e.g. the user manually runs the same report every Monday), point it out and offer to formalise it.
***
## 12. Quick reference: n8n JSON node block shape
```json theme={null}
{
"id": "",
"name": "VH3 AI",
"type": "n8n-nodes-vh3ai.vh3Ai",
"typeVersion": 1,
"position": [800, 300],
"credentials": {
"vh3AiApi": {
"id": "",
"name": "VH3 AI API"
}
},
"parameters": {
"resource": "jobFeed",
"operation": "aggregateJobs",
"metric": "job_count",
"period": "last_7_days",
"timeAxis": "actualStartAt",
"additionalFields": {
"groupBy": "resourceId",
"compareTo": "previous_period"
}
}
}
```
The `subtitle` expression on the node is:
`={{$parameter["operation"] + " (" + $parameter["resource"] + ")"}}` — you do not need to set it manually in JSON.
***
## Related
Installation, credentials, hosting, and operation list.
System prompt for AI Agent node workflows.
Official integration page and full action catalogue.
Source code, changelog, and contribution guide.
# Agent Starter Kits
Source: https://docs.vh3.ai/agent-kits/overview
Ready-to-use configurations for connecting AI agents and coding assistants to the VH3 intelligence layer
# Agent Starter Kits
VH3 AI exposes the full intelligence layer, graph, semantic index, aggregation, sentinels, reports, through a standard API and an MCP surface. These starter kits give your AI tools the exact configuration they need to use that surface correctly from day one.
Each kit is self-contained. Pick the one that matches how your team works.
**Operators:** these kits are for builders connecting AI tools to the platform. If you run the operation day to day (coordinator, dispatcher, account manager, engineer, owner), start at [Working with your operation](/guides/working-with-your-operation) instead.
## For AI agents (documentation)
This site is optimised for LLMs and coding agents. Use these endpoints to learn the VH3 API. They search **documentation only**, not your live field service data.
| Resource | URL |
| ----------------------- | ------------------------------------------------------------------ |
| Site index | [docs.vh3.ai/llms.txt](https://docs.vh3.ai/llms.txt) |
| Full docs (single file) | [docs.vh3.ai/llms-full.txt](https://docs.vh3.ai/llms-full.txt) |
| Any page as Markdown | Add `.md` to the page URL, or use **Copy page** in the header menu |
| Documentation MCP | [docs.vh3.ai/mcp](https://docs.vh3.ai/mcp) |
**Two different MCP servers.** The URL above is Mintlify's **documentation** MCP (search and read these docs). To query live jobs, sentinels, and reports, use the [VH3 product MCP](/agent-kits/mcp-setup) with your tenant JWT, not the docs MCP.
npx skills add [https://docs.vh3.ai](https://docs.vh3.ai)
On any page, open the **contextual menu** (top of page) to copy the page as Markdown, open it in Claude or ChatGPT, or connect the documentation MCP to Cursor or VS Code in one click.
A drop-in context file for AI coding agents (Cursor, Claude Code, GitHub Copilot). Tells the agent which endpoint to call for which question, the correct field names, and the API conventions.
Three `.cursor/rules/` files that shape every VH3-related code generation in Cursor, domain vocabulary, API call patterns, and n8n workflow conventions.
Connect any MCP-compatible client (Claude Desktop, Cursor, custom agents) directly to the VH3 intelligence layer. No middleware required.
Project instructions for Claude.ai, for operations managers who want to query VH3 in plain English without writing code.
Anthropic SKILL.md template for Claude Code and MCP clients: tool routing, valid parameters, and ops response format.
System prompts for n8n AI Agent workflows using the VH3 AI node and 1,000+ app connectors.
Verified community node on n8n — install steps, full action list, and integration overview.
## Which kit should I use?
| Your situation | Recommended kit |
| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| You're a developer using Cursor | [AGENTS.md](/agent-kits/agents-md) + [Cursor Rules](/agent-kits/cursor-rules) |
| You want to connect Claude Desktop or another MCP client | [MCP Server](/agent-kits/mcp-setup) |
| You're building an AI-powered Claude.ai workspace for your ops team | [Claude.ai Projects](/agent-kits/claude-projects) |
| You're using Claude Code or Anthropic-format skills with the VH3 MCP server | [Claude Skills](/agent-kits/claude-skills) |
| You're building automations in n8n with an LLM decision layer | [n8n Agent Prompts](/agent-kits/n8n-agents) · [Install the verified node](https://link.vh3.ai/n8n) |
| You want everything | Start with AGENTS.md, add MCP, then layer in the tool-specific kits |
## What the kits don't do
These kits configure AI tools to use the VH3 API correctly. They do not replace the API itself, you still need a valid `company_id` and `api_key` to make calls. See [Authentication](/authentication) for how to obtain those.
The kits reference endpoints from the [API Reference](/api-reference/overview). If an endpoint behaves unexpectedly, cross-check the spec there, the starter kits are tuned for the current API version.
# Contacts
Source: https://docs.vh3.ai/api-reference/bigchange/contacts
BigChange contacts, groups, and site access hours
# Contacts
BigChange contacts, groups, and site access hours. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Date filters (list)
`POST /contacts/list` accepts optional `createdAtFrom` (ISO 8601 UTC). Any creation-date window used with an upper bound must stay within the **12-month** BigChange limit. See [overview](/api-reference/bigchange/overview#date-ranges).
## Contacts
Customer and site records.
### `GET` `/contacts/contact`
Get contact.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/contacts/contact" \
-H "X-API-Key: your-api-key" \
--data-urlencode "contactId=12345"
```
### `POST` `/contacts/create`
Create contact.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contacts/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme",
"reference": "ACME-01"
}'
```
### `POST` `/contacts/edit`
Update contact.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contacts/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"name": "Acme Ltd"
}'
```
### `POST` `/contacts/list`
List contacts.
| Field | Type | Required | Description |
| --------------- | ------ | -------- | ------------------------------------------- |
| `createdAtFrom` | string | No | Contacts created on or after (ISO 8601 UTC) |
| `sortBy` | string | No | `createdAt` or `name` |
| `direction` | enum | No | `ascending` or `descending` |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contacts/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50,
"createdAtFrom": "2025-04-01T00:00:00Z",
"sortBy": "name",
"direction": "ascending"
}'
```
### `POST` `/contacts/on_stop`
Put on stop.
**Enum values:**
* **status:** `contactOnStop`, `creditLimitOnStop`
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contacts/on_stop" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"status": "contactOnStop",
"stopReason": "Credit hold"
}'
```
### `POST` `/contacts/unstop`
Remove stop.
**Enum values:**
* **appliesTo:** `contactOnly`, `contactAndChildren`
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contacts/unstop" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"appliesTo": "contactOnly"
}'
```
### `POST` `/contacts/site_access_hours_list`
List access hours.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contacts/site_access_hours_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"pageNumber": 1,
"pageSize": 10
}'
```
### `POST` `/contacts/site_access_hours_update`
Update access hours.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contacts/site_access_hours_update" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"body": [
{
"dayOfWeek": "monday",
"startTime": "08:00",
"endTime": "17:00"
}
]
}'
```
## Contact groups
Organise contacts.
### `GET` `/contact_groups/contact_group`
Get group.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/contact_groups/contact_group" \
-H "X-API-Key: your-api-key" \
--data-urlencode "contactGroupId=99"
```
### `POST` `/contact_groups/create`
Create group.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contact_groups/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Retail"
}'
```
### `POST` `/contact_groups/list`
List groups.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contact_groups/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
### `POST` `/contact_groups/update`
Update group.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/contact_groups/update" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactGroupId": 99,
"name": "Retail UK"
}'
```
# Invoices
Source: https://docs.vh3.ai/api-reference/bigchange/invoices
BigChange invoices and line items
# Invoices
BigChange invoices and line items. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Date filters (list)
`POST /invoices/list` accepts an optional creation-date window. **`createdAtTo` minus `createdAtFrom` must not exceed 12 months\`** (BigChange API limit, see [overview](/api-reference/bigchange/overview#date-ranges)).
| Param | Type | Required | Description |
| --------------- | ------ | -------- | --------------------------------------------------------- |
| `createdAtFrom` | string | No | Invoices created on or after this instant (ISO 8601 UTC) |
| `createdAtTo` | string | No | Invoices created on or before this instant (ISO 8601 UTC) |
Combine with `id`, `jobId`, `jobGroupId`, `contactId`, or `reference` (comma-separated lists, max 50 IDs each). Use `sortBy: "createdAt"` with `direction` when reporting by period.
## Invoices
Billing.
### `GET` `/invoices/invoice`
Get invoice.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/invoices/invoice" \
-H "X-API-Key: your-api-key" \
--data-urlencode "invoiceId=5001"
```
### `POST` `/invoices/create`
Create invoice.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"createdAt": "2026-04-01T00:00:00Z"
}'
```
### `POST` `/invoices/edit`
Update invoice.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": 5001
}'
```
### `POST` `/invoices/list`
List invoices with optional filters and a creation-date range (max **12 months** between `createdAtFrom` and `createdAtTo`).
**Request body (filters):**
| Field | Type | Required | Description |
| --------------- | ------- | -------- | --------------------------------------- |
| `pageNumber` | integer | No | Page index (1-based) |
| `pageSize` | integer | No | Items per page |
| `createdAtFrom` | string | No | Created on or after (ISO 8601 UTC) |
| `createdAtTo` | string | No | Created on or before (ISO 8601 UTC) |
| `contactId` | string | No | Contact IDs (comma-separated, max 50) |
| `jobId` | string | No | Job IDs (comma-separated, max 50) |
| `jobGroupId` | string | No | Job group IDs (comma-separated, max 50) |
| `id` | string | No | Invoice IDs (comma-separated, max 50) |
| `reference` | string | No | References (comma-separated, max 50) |
| `sortBy` | string | No | `createdAt` |
| `direction` | enum | No | `ascending` or `descending` |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50,
"createdAtFrom": "2026-01-01T00:00:00Z",
"createdAtTo": "2026-03-31T23:59:59Z",
"contactId": "12345",
"sortBy": "createdAt",
"direction": "descending"
}'
```
### `POST` `/invoices/cancel`
Cancel.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/cancel" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": 5001
}'
```
### `POST` `/invoices/mark_paid`
Mark paid. Optional `paidAt` (ISO 8601 UTC); defaults to now if omitted. Single timestamp, not a date range.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/mark_paid" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": 5001,
"paidAt": "2026-04-15T12:00:00Z"
}'
```
### `POST` `/invoices/mark_sent`
Mark sent. Optional `sentAt` (ISO 8601 UTC); defaults to now if omitted.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/mark_sent" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": 5001,
"sentAt": "2026-04-10T09:00:00Z"
}'
```
### `POST` `/invoices/document/create`
Generate PDF.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/document/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": 5001
}'
```
## Invoice line items
Line-level charges.
### `GET` `/invoices/line_item`
Get line.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/invoices/line_item" \
-H "X-API-Key: your-api-key" \
--data-urlencode "invoiceId=5001" \
--data-urlencode "lineItemId=1"
```
### `GET` `/invoices/line_item/edit`
Update line.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/invoices/line_item/edit" \
-H "X-API-Key: your-api-key" \
--data-urlencode "invoiceId=5001" \
--data-urlencode "lineItemId=1"
```
### `POST` `/invoices/line_item/create`
Create line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/line_item/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": 5001,
"description": "Labour",
"quantity": 2,
"unitSellingPrice": 85
}'
```
### `POST` `/invoices/line_item/delete`
Delete line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/line_item/delete" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": 5001,
"lineItemId": 1
}'
```
### `POST` `/invoices/line_item/list`
List lines.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/invoices/line_item/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": 5001,
"pageNumber": 1,
"pageSize": 50
}'
```
# Jobs
Source: https://docs.vh3.ai/api-reference/bigchange/jobs
BigChange jobs, constraints, stock, groups, and types
# Jobs
BigChange jobs, constraints, stock, groups, and types. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Date filters (list)
`POST /jobs/list` requires **`createdAtFrom` and `createdAtTo`** (job creation time, ISO 8601 UTC). The span between them **must not exceed 12 months**. See [overview](/api-reference/bigchange/overview#date-ranges).
## Jobs
Job lifecycle.
### `GET` `/jobs/job`
Get job.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/jobs/job" \
-H "X-API-Key: your-api-key" \
--data-urlencode "jobId=12345"
```
### `POST` `/jobs/create`
Create job.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"typeId": 42,
"contactId": 12345,
"description": "Blocked toilet"
}'
```
### `POST` `/jobs/edit`
Update job.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"description": "Updated description"
}'
```
### `POST` `/jobs/list`
List jobs. **`createdAtFrom` and `createdAtTo` are required.** Max **12 months** between them.
**Request body (key fields):**
| Field | Type | Required | Description |
| --------------- | ------- | -------- | ---------------------------------------- |
| `createdAtFrom` | string | **Yes** | Jobs created on or after (ISO 8601 UTC) |
| `createdAtTo` | string | **Yes** | Jobs created on or before (ISO 8601 UTC) |
| `pageNumber` | integer | No | Page index |
| `pageSize` | integer | No | Items per page |
| `direction` | enum | No | `ascending` or `descending` |
| `contactId` | string | No | Filter by contact IDs (comma-separated) |
| `resourceId` | string | No | Filter by engineer IDs |
| `status` | string | No | Filter by job status |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 20,
"createdAtFrom": "2026-01-01T00:00:00Z",
"createdAtTo": "2026-03-31T23:59:59Z",
"direction": "descending"
}'
```
### `POST` `/jobs/cancel`
Cancel job.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/cancel" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"reason": "Customer cancelled"
}'
```
### `POST` `/jobs/start`
Start job.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/start" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"comment": "On site"
}'
```
### `POST` `/jobs/result`
Set result.
**Enum values:**
* **status:** `completedOk`, `completedWithIssues`
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/result" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"status": "completedOk",
"result": "Job complete"
}'
```
### `POST` `/jobs/scheduling`
Schedule job.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/scheduling" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"resourceId": 100,
"vehicleId": 50,
"plannedStartAt": "2026-04-20T09:00:00Z"
}'
```
### `POST` `/jobs/status/history`
Status history.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/status/history" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"pageNumber": 1,
"pageSize": 50
}'
```
## Job constraints
Scheduling constraints.
### `POST` `/jobs/constraints/create`
Create constraint.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/constraints/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345
}'
```
### `POST` `/jobs/constraints/delete`
Delete constraint.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/constraints/delete" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"constraintId": 1
}'
```
### `POST` `/jobs/constraints/list`
List constraints.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/constraints/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"pageNumber": 1,
"pageSize": 20
}'
```
## Job stock
Parts on jobs.
### `POST` `/jobs/stock/create`
Add stock line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/stock/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"stockDetailsId": 10,
"quantityPlanned": 1
}'
```
### `POST` `/jobs/stock/delete`
Remove stock line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/stock/delete" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"jobStockId": 5
}'
```
### `POST` `/jobs/stock/get`
Get stock line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/stock/get" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"jobStockId": 5
}'
```
### `POST` `/jobs/stock/list`
List stock lines.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/stock/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"pageNumber": 1,
"pageSize": 20
}'
```
## Job groups
Multi-job programmes.
### `POST` `/job_groups/create`
Create group.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_groups/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Refurb phase 1"
}'
```
### `POST` `/job_groups/edit`
Update group.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_groups/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobGroupId": 10,
"name": "Refurb phase 1"
}'
```
### `POST` `/job_groups/job_group`
Get group.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_groups/job_group" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobGroupId": 10
}'
```
### `POST` `/job_groups/list`
List groups.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_groups/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 20
}'
```
### `POST` `/job_groups/status_history`
Group status history.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_groups/status_history" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobGroupId": 10,
"pageNumber": 1,
"pageSize": 20
}'
```
### `POST` `/job_groups/job_group_results_as_complete`
Mark complete.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_groups/job_group_results_as_complete" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobGroupId": 10
}'
```
### `POST` `/job_groups/job_group_results_as_financially_complete`
Mark financially complete.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_groups/job_group_results_as_financially_complete" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobGroupId": 10
}'
```
## Job types
Job type catalogue.
### `POST` `/job_types/job_types`
Get type.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_types/job_types" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobTypeId": 42
}'
```
### `POST` `/job_types/list`
List types.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/job_types/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 100
}'
```
# Notes
Source: https://docs.vh3.ai/api-reference/bigchange/notes
Notes and note types
# Notes
Notes and note types. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Notes
Entity notes.
### `GET` `/notes/note`
Get note.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/notes/note" \
-H "X-API-Key: your-api-key" \
--data-urlencode "id=7001"
```
### `POST` `/notes/create`
Create note.
**Enum values:**
* **entityType:** `contact`, `job`, `resource`, `stockItem`, `vehicle`, `salesOpportunity`, `contract`
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/notes/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"entityType": "job",
"entityId": 12345,
"typeId": 1,
"subject": "Follow-up"
}'
```
### `POST` `/notes/edit`
Update note.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/notes/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"noteId": 7001,
"subject": "Updated"
}'
```
### `POST` `/notes/list`
List notes.
**Enum values:**
* **status:** `open`, `completed`, `cancelled`
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/notes/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"entityType": "job",
"entityId": 12345,
"status": "open",
"pageNumber": 1,
"pageSize": 50
}'
```
### `POST` `/notes/progress_update`
Update progress.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/notes/progress_update" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"noteId": 7001,
"percentage": 50
}'
```
## Note types
Note type definitions.
### `GET` `/note_types/note`
Get type.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/note_types/note" \
-H "X-API-Key: your-api-key" \
--data-urlencode "noteTypeId=1"
```
### `POST` `/note_types/list`
List types.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/note_types/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
# BigChange API Overview
Source: https://docs.vh3.ai/api-reference/bigchange/overview
BigChange API Integration, jobs, contacts, finance, stock, and worksheets
# BigChange API
Unified read/write proxy to your BigChange field service data. Covers jobs, contacts, invoices, quotes, sales opportunities, purchase orders, resources, vehicles, stock, worksheets, and reference data.
Tenant scope is resolved from your API key. No `company_id` is required on these requests.
We've added some usefuil features such as pre handled authentication, compactions and data output optimisation.
## Base URL
```
https://api.vh3connect.io/api:YdihQNr3
```
## Authentication
Pass your VH3 API key in the `X-API-Key` header on every request. This is the same key issued for the [VH3 AI Intelligence](/api-reference/overview) layer; only the transport differs.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 20
}'
```
| Header | Required | Description |
| -------------- | ---------- | ------------------- |
| `X-API-Key` | Yes | Your tenant API key |
| `Content-Type` | Yes (POST) | `application/json` |
Missing or invalid keys return `401 Unauthorised`.
See [Authentication](/authentication) for the full two-API comparison.
## Common response codes
| Code | Meaning |
| ----- | ------------------------------------------ |
| `200` | Success |
| `201` | Created |
| `400` | Bad request, invalid or missing parameters |
| `401` | Unauthorised, missing or invalid API key |
| `403` | Forbidden, insufficient permissions |
| `404` | Not found |
| `422` | Validation error |
| `429` | Rate limited |
| `500` | Internal server error |
## Pagination
List endpoints accept `pageNumber` (1-based) and `pageSize`. Finance list responses also include `pageItemCount` (items in the current page, use to detect the last page).
| Param | Default | Max |
| ---------- | ------- | ---- |
| `pageSize` | 100 | 1000 |
## Sorting
Most list endpoints accept:
| Param | Values |
| ----------- | --------------------------------------------------------- |
| `sortBy` | Field name (varies by endpoint, e.g. `name`, `createdAt`) |
| `direction` | `ascending` or `descending` |
## Date ranges
BigChange enforces a **maximum 12-month window** on date-range filters. If `createdAtTo` minus `createdAtFrom` (or equivalent pair) exceeds twelve calendar months, the API returns a validation error.
| Rule | Detail |
| ------------ | --------------------------------------------------------------------------------------- |
| Format | ISO 8601 UTC, e.g. `2026-01-01T00:00:00Z` |
| Typical pair | `createdAtFrom` + `createdAtTo`, inclusive bounds on record creation time |
| Max span | **12 months**, always; not configurable per tenant |
| Sort tie-in | Finance lists (`invoices`, `quotes`) usually sort by `createdAt` when filtering by date |
**Where date ranges apply:**
| Endpoint | Date filter fields | Notes |
| -------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------ |
| `POST /jobs/list` | `createdAtFrom`, `createdAtTo` | Required for job list queries |
| `POST /contacts/list` | `createdAtFrom` | Optional lower bound on contact creation |
| `POST /invoices/list` | `createdAtFrom`, `createdAtTo` | Optional; combine with `contactId`, `jobId`, `reference`, etc. |
| `POST /quotes/list` | `createdAtFrom`, `createdAtTo` | Optional; same pattern as invoices |
| `POST /purchase_orders/list` | `createdAtFrom`, `createdAtTo` | At least one non-date filter still required |
| `POST /sales_opportunities/list` | `createdAtFrom`, `createdAtTo`, `dueDateFrom`, `dueDateTo` | At least one filter required; due-date pair also subject to 12-month max |
Status timestamps on write endpoints (`paidAt`, `sentAt`, `plannedStartAt`, note `dueAt`) are single instants, not ranges, they are not subject to the 12-month window rule.
## Custom fields
Pass custom fields as an array when creating or updating records:
```json theme={null}
{
"customFields": [
{ "definitionId": 123, "value": "High priority" },
{ "definitionId": 456, "value": null }
]
}
```
Set `value` to `null` to clear an existing value.
## Common enum values
| Domain | Field | Values |
| --------- | ------------------------- | ------------------------------------------------------------------------------------ |
| All lists | `direction` | `ascending`, `descending` |
| Contacts | `status` (on stop) | `contactOnStop`, `creditLimitOnStop` |
| Contacts | `appliesTo` (stop/unstop) | `contactOnly`, `contactAndChildren` |
| Jobs | `status` (result) | `completedOk`, `completedWithIssues` |
| Notes | `status` | `open`, `completed`, `cancelled` |
| Notes | `entityType` | `contact`, `job`, `resource`, `stockItem`, `vehicle`, `salesOpportunity`, `contract` |
| Persons | `consent.status` | `awaiting`, `refused`, `granted` |
| Persons | `consent.medium` | `email`, `click`, `telephone` |
Endpoint-specific enums are listed on each page where they apply.
## Path format
Request URLs are `{baseUrl}{path}` with **one** slash between base and path, e.g. `https://api.vh3connect.io/api:YdihQNr3` + `/jobs/list`. Some BigChange routes include repeated segments by design (e.g. `/stock/stock/item_get`); that is not a double-slash error.
## Endpoint groups
| Group | Description |
| ------------------------------------------------------------------- | ------------------------------------------------------ |
| [Contacts](/api-reference/bigchange/contacts) | Contacts, groups, site access hours, on-stop |
| [Jobs](/api-reference/bigchange/jobs) | Jobs, constraints, stock, groups, types |
| [Invoices](/api-reference/bigchange/invoices) | Invoices and line items |
| [Quotes](/api-reference/bigchange/quotes) | Quotes and line items |
| [Sales opportunities](/api-reference/bigchange/sales-opportunities) | Opportunities, stages, probabilities, line items |
| [Purchase orders](/api-reference/bigchange/purchase-orders) | Purchase orders, series, line items |
| [Notes](/api-reference/bigchange/notes) | Notes and note types |
| [Persons](/api-reference/bigchange/persons) | Site contacts and consent |
| [Resources](/api-reference/bigchange/resources) | Engineers/technicians and resource groups |
| [Vehicles](/api-reference/bigchange/vehicles) | Fleet vehicles |
| [Stock](/api-reference/bigchange/stock) | Stock details, items, movements, suppliers, categories |
| [Worksheets](/api-reference/bigchange/worksheets) | Worksheet definitions, questions, answers |
| [Reference data](/api-reference/bigchange/reference-data) | Department and nominal codes |
# Persons
Source: https://docs.vh3.ai/api-reference/bigchange/persons
Site contacts and consent
# Persons
Site contacts and consent. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Persons
People on accounts.
### `GET` `/persons/person`
Get person.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/persons/person" \
-H "X-API-Key: your-api-key" \
--data-urlencode "personId=550e8400-e29b-41d4-a716-446655440000"
```
### `POST` `/persons/create`
Create person.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/persons/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"firstName": "Jane",
"surname": "Smith",
"email": "jane@example.com"
}'
```
### `POST` `/persons/edit`
Update person.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/persons/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"personId": "550e8400-e29b-41d4-a716-446655440000"
}'
```
### `POST` `/persons/list`
List persons.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/persons/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"pageNumber": 1,
"pageSize": 25
}'
```
### `POST` `/persons/consent/set`
Set consent.
**Enum values:**
* **status:** `awaiting`, `refused`, `granted`
* **medium:** `email`, `click`, `telephone`
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/persons/consent/set" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"personId": "550e8400-e29b-41d4-a716-446655440000",
"status": "granted",
"medium": "email"
}'
```
### `POST` `/persons/consent/history`
Consent history.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/persons/consent/history" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"personId": "550e8400-e29b-41d4-a716-446655440000",
"pageNumber": 1,
"pageSize": 20
}'
```
# Purchase Orders
Source: https://docs.vh3.ai/api-reference/bigchange/purchase-orders
POs, series, and lines
# Purchase Orders
POs, series, and lines. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Date filters (list)
`POST /purchase_orders/list` requires **at least one filter** (`id`, `jobId`, `jobGroupId`, `contactId`, `reference`, or a date pair). Optional `createdAtFrom` / `createdAtTo` on PO creation time, **max 12 months** between them. See [overview](/api-reference/bigchange/overview#date-ranges).
## Purchase orders
Procurement.
### `GET` `/purchase_orders/purchase_order`
Get PO.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/purchase_order" \
-H "X-API-Key: your-api-key" \
--data-urlencode "id=4001"
```
### `POST` `/purchase_orders/create`
Create PO.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"supplierId": 999,
"contactId": 12345
}'
```
### `POST` `/purchase_orders/edit`
Update PO.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"id": 4001
}'
```
### `POST` `/purchase_orders/list`
List purchase orders. **At least one filter is required.** Date range optional; max **12 months** on `createdAtFrom` → `createdAtTo`.
| Field | Type | Required | Description |
| --------------- | ------- | --------- | ----------------------------------- |
| `jobId` | integer | One of… | Filter by job |
| `contactId` | integer | …required | Filter by contact |
| `id` | integer | filters | Filter by PO id |
| `reference` | string | | Filter by reference |
| `createdAtFrom` | string | | Created on or after (ISO 8601 UTC) |
| `createdAtTo` | string | | Created on or before (ISO 8601 UTC) |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"jobId": 12345,
"createdAtFrom": "2026-01-01T00:00:00Z",
"createdAtTo": "2026-03-31T23:59:59Z",
"pageNumber": 1,
"pageSize": 50
}'
```
### `POST` `/purchase_orders/series/list`
List series.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/series/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
### `GET` `/purchase_orders/series`
Get series.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/series" \
-H "X-API-Key: your-api-key" \
--data-urlencode "id=10"
```
## Line items
PO lines.
### `GET` `/purchase_orders/line_item`
Get line.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/line_item" \
-H "X-API-Key: your-api-key" \
--data-urlencode "purchaseOrderId=4001" \
--data-urlencode "id=1"
```
### `POST` `/purchase_orders/line_item/list`
List lines.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/line_item/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"purchaseOrderId": 4001,
"pageNumber": 1,
"pageSize": 50
}'
```
### `POST` `/purchase_orders/line_item/create`
Create line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/line_item/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"purchaseOrderId": 4001
}'
```
### `POST` `/purchase_orders/line_item/edit`
Update line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/line_item/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"purchaseOrderId": 4001,
"id": 1
}'
```
### `POST` `/purchase_orders/line_item/delete`
Delete line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/purchase_orders/line_item/delete" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"purchaseOrderId": 4001,
"id": 1
}'
```
# Quotes
Source: https://docs.vh3.ai/api-reference/bigchange/quotes
BigChange quotes and line items
# Quotes
BigChange quotes and line items. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Date filters (list)
`POST /quotes/list` supports the same creation-date window as invoices: `createdAtFrom` and `createdAtTo` (ISO 8601 UTC). **The range must not exceed 12 months.** See [overview](/api-reference/bigchange/overview#date-ranges).
| Param | Type | Required | Description |
| --------------- | ------ | -------- | ---------------------------------------- |
| `createdAtFrom` | string | No | Quotes created on or after this instant |
| `createdAtTo` | string | No | Quotes created on or before this instant |
Optional filters: `id`, `jobId`, `jobGroupId`, `contactId`, `reference` (comma-separated, max 50 each).
## Quotes
Quotations.
### `GET` `/quotes/quote`
Get quote.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/quotes/quote" \
-H "X-API-Key: your-api-key" \
--data-urlencode "quoteId=3001"
```
### `POST` `/quotes/create`
Create quote.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345
}'
```
### `POST` `/quotes/edit`
Update quote.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"quoteId": 3001
}'
```
### `POST` `/quotes/list`
List quotes with optional filters and creation-date range (max **12 months** between `createdAtFrom` and `createdAtTo`).
**Request body (filters):**
| Field | Type | Required | Description |
| --------------- | ------- | -------- | --------------------------------------- |
| `pageNumber` | integer | No | Page index (1-based) |
| `pageSize` | integer | No | Items per page |
| `createdAtFrom` | string | No | Created on or after (ISO 8601 UTC) |
| `createdAtTo` | string | No | Created on or before (ISO 8601 UTC) |
| `contactId` | string | No | Contact IDs (comma-separated, max 50) |
| `jobId` | string | No | Job IDs (comma-separated, max 50) |
| `jobGroupId` | string | No | Job group IDs (comma-separated, max 50) |
| `id` | string | No | Quote IDs (comma-separated, max 50) |
| `reference` | string | No | References (comma-separated, max 50) |
| `sortBy` | string | No | Typically `createdAt` |
| `direction` | enum | No | `ascending` or `descending` |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50,
"createdAtFrom": "2026-01-01T00:00:00Z",
"createdAtTo": "2026-06-30T23:59:59Z",
"contactId": "12345",
"sortBy": "createdAt",
"direction": "descending"
}'
```
### `POST` `/quotes/mark_sent`
Mark sent.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/mark_sent" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"quoteId": 3001
}'
```
### `POST` `/quotes/mark_accepted`
Mark accepted.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/mark_accepted" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"quoteId": 3001
}'
```
### `POST` `/quotes/mark_rejected`
Mark rejected.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/mark_rejected" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"quoteId": 3001
}'
```
## Quote line items
Quote lines.
### `GET` `/quotes/line_item`
Get line.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/quotes/line_item" \
-H "X-API-Key: your-api-key" \
--data-urlencode "quoteId=3001" \
--data-urlencode "lineItemId=1"
```
### `POST` `/quotes/line_item/create`
Create line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/line_item/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"quoteId": 3001,
"description": "Boiler service",
"quantity": 1
}'
```
### `POST` `/quotes/line_item/edit`
Update line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/line_item/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"quoteId": 3001,
"lineItemId": 1
}'
```
### `POST` `/quotes/line_item/delete`
Delete line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/line_item/delete" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"quoteId": 3001,
"lineItemId": 1
}'
```
### `POST` `/quotes/line_item/list`
List lines.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/quotes/line_item/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"quoteId": 3001,
"pageNumber": 1,
"pageSize": 50
}'
```
# Reference Data
Source: https://docs.vh3.ai/api-reference/bigchange/reference-data
Department and nominal codes
# Reference Data
Department and nominal codes. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Department codes
Departments.
### `POST` `/reference_data/department_codes_list`
List codes.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/reference_data/department_codes_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 100
}'
```
### `GET` `/reference_data/retrieves_details`
Get code.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/reference_data/retrieves_details" \
-H "X-API-Key: your-api-key" \
--data-urlencode "departmentCodeId=1"
```
## Nominal codes
Nominal accounts.
### `POST` `/reference_data/normalt_codes_list`
List codes.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/reference_data/normalt_codes_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 100
}'
```
### `GET` `/reference_data/nominal_code_id`
Get code.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/reference_data/nominal_code_id" \
-H "X-API-Key: your-api-key" \
--data-urlencode "nominalCodeId=1"
```
# Resources
Source: https://docs.vh3.ai/api-reference/bigchange/resources
Engineers and resource groups
# Resources
Engineers and resource groups. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Resources
Engineers/technicians.
### `GET` `/resources/resource_get`
Get resource.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/resources/resource_get" \
-H "X-API-Key: your-api-key" \
--data-urlencode "resourceId=100"
```
### `POST` `/resources/resource_create`
Create resource.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/resources/resource_create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Alex Engineer",
"groupId": 5
}'
```
### `POST` `/resources/update`
Update resource.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/resources/update" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"resourceId": 100,
"name": "Alex Engineer"
}'
```
### `POST` `/resources/resources_list`
List resources.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/resources/resources_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
## Resource groups
Teams.
### `GET` `/resource_groups/resource_group/get`
Get group.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/resource_groups/resource_group/get" \
-H "X-API-Key: your-api-key" \
--data-urlencode "resourceGroupId=5"
```
### `POST` `/resource_groups/list`
List groups.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/resource_groups/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
# Sales Opportunities
Source: https://docs.vh3.ai/api-reference/bigchange/sales-opportunities
Pipeline and line items
# Sales Opportunities
Pipeline and line items. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Date filters (list)
`POST /sales_opportunities/list` requires **at least one filter**. Two independent windows are available; each pair is limited to **12 months**:
| Param | Filters on |
| ------------------------------- | ------------------------- |
| `createdAtFrom` / `createdAtTo` | Opportunity creation time |
| `dueDateFrom` / `dueDateTo` | Opportunity due date |
See [overview](/api-reference/bigchange/overview#date-ranges).
## Sales opportunities
CRM pipeline.
### `GET` `/sales_opportunities/sales_opportunity`
Get opportunity.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/sales_opportunity" \
-H "X-API-Key: your-api-key" \
--data-urlencode "id=2001"
```
### `POST` `/sales_opportunities/list`
List opportunities. **At least one of:** `id`, `status`, `contactId`, `ownerId`, `reference`, `createdAtFrom`/`createdAtTo`, or `dueDateFrom`/`dueDateTo`.
| Field | Type | Description |
| --------------- | ------- | ------------------------------------------------------------------------ |
| `contactId` | integer | Customer contact |
| `createdAtFrom` | string | Created on or after (ISO 8601 UTC, max 12-month span with `createdAtTo`) |
| `createdAtTo` | string | Created on or before |
| `dueDateFrom` | string | Due on or after (max 12-month span with `dueDateTo`) |
| `dueDateTo` | string | Due on or before |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contactId": 12345,
"createdAtFrom": "2026-01-01T00:00:00Z",
"createdAtTo": "2026-06-30T23:59:59Z",
"pageNumber": 1,
"pageSize": 50
}'
```
### `POST` `/sales_opportunities/edit`
Update.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"id": 2001
}'
```
### `POST` `/sales_opportunities/probabilities/list`
List probabilities.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/probabilities/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
### `POST` `/sales_opportunities/stages/list`
List stages.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/stages/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
## Line items
Opportunity lines.
### `GET` `/sales_opportunities/line_item`
Get line.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/line_item" \
-H "X-API-Key: your-api-key" \
--data-urlencode "salesOpportunityId=2001" \
--data-urlencode "id=1"
```
### `POST` `/sales_opportunities/line_item/list`
List lines.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/line_item/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"salesOpportunityId": 2001,
"pageNumber": 1,
"pageSize": 50
}'
```
### `POST` `/sales_opportunities/line_item/create`
Create line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/line_item/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"salesOpportunityId": 2001
}'
```
### `POST` `/sales_opportunities/line_item/edit`
Update line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/line_item/edit" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"salesOpportunityId": 2001,
"id": 1
}'
```
### `POST` `/sales_opportunities/line_item/delete`
Delete line.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/sales_opportunities/line_item/delete" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"salesOpportunityId": 2001,
"id": 1
}'
```
# Stock
Source: https://docs.vh3.ai/api-reference/bigchange/stock
Inventory, movements, suppliers
# Stock
Inventory, movements, suppliers. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
Note: path `/stock/stock/item_get` is correct, the segment `stock` appears twice in the BigChange route, not a documentation typo.
## Stock details
Product catalogue.
### `GET` `/stock/stock_details`
Get details.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/stock/stock_details" \
-H "X-API-Key: your-api-key" \
--data-urlencode "stockDetailsId=10"
```
### `POST` `/stock/stock_details_create`
Create details.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_details_create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "Thermostat T100"
}'
```
### `POST` `/stock/stock_details_update`
Update details.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_details_update" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"stockDetailsId": 10
}'
```
### `POST` `/stock/stock_details_list`
List details.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_details_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
## Stock items
Physical stock.
### `GET` `/stock/stock/item_get`
Get item.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/stock/stock/item_get" \
-H "X-API-Key: your-api-key" \
--data-urlencode "stockItemId=20"
```
### `POST` `/stock/stock_item_create`
Create item.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_item_create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"stockDetailsId": 10,
"quantity": 5
}'
```
### `POST` `/stock/stock_item_update`
Update item.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_item_update" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"stockItemId": 20
}'
```
### `POST` `/stock/stock_item_list`
List items.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_item_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
## Movements
Stock movements.
### `POST` `/stock/stock_movements_list`
List movements.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_movements_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
## Product categories
Categories.
### `GET` `/stock/product_categories/get`
Get category.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/stock/product_categories/get" \
-H "X-API-Key: your-api-key" \
--data-urlencode "productCategoryId=3"
```
### `POST` `/stock/product_categories_list`
List categories.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/product_categories_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
## Suppliers
Stock suppliers.
### `GET` `/stock/stock_supplier_get`
Get supplier.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/stock/stock_supplier_get" \
-H "X-API-Key: your-api-key" \
--data-urlencode "id=1"
```
### `POST` `/stock/stock_supplier_create`
Add supplier.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_supplier_create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"stockDetailsId": 10,
"contactId": 999
}'
```
### `POST` `/stock/stock_supplier_update`
Update supplier.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_supplier_update" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"id": 1
}'
```
### `POST` `/stock/stock_supplier_list`
List suppliers.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/stock/stock_supplier_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"stockDetailsId": 10,
"pageNumber": 1,
"pageSize": 20
}'
```
# Vehicles
Source: https://docs.vh3.ai/api-reference/bigchange/vehicles
Fleet vehicles
# Vehicles
Fleet vehicles. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Vehicles
Fleet.
### `GET` `/vehicles/vehicle_get`
Get vehicle.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/vehicles/vehicle_get" \
-H "X-API-Key: your-api-key" \
--data-urlencode "vehicleId=50"
```
### `POST` `/vehicles/create`
Create vehicle.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/vehicles/create" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registration": "AB12 CDE"
}'
```
### `POST` `/vehicles/update`
Update vehicle.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/vehicles/update" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"vehicleId": 50
}'
```
### `POST` `/vehicles/list`
List vehicles.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/vehicles/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
# Worksheets
Source: https://docs.vh3.ai/api-reference/bigchange/worksheets
Forms and answers
# Worksheets
Forms and answers. Auth: `X-API-Key` header. Base: `https://api.vh3connect.io/api:YdihQNr3`.
## Shared parameters
| Param | Type | Description |
| ------------ | ------- | -------------------------------------- |
| `pageNumber` | integer | Page index (1-based) |
| `pageSize` | integer | Items per page (default 100, max 1000) |
| `sortBy` | string | Sort field (endpoint-specific) |
| `direction` | enum | `ascending` or `descending` |
## Worksheets
Digital forms.
### `GET` `/worksheet/worksheet_get`
Get worksheet.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/worksheet/worksheet_get" \
-H "X-API-Key: your-api-key" \
--data-urlencode "worksheetId=1"
```
### `POST` `/worksheet/worksheet_list`
List worksheets.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/worksheet/worksheet_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
### `POST` `/worksheet/worksheet_questions_get`
Get questions.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/worksheet/worksheet_questions_get" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"worksheetId": 1,
"pageNumber": 1,
"pageSize": 100
}'
```
### `POST` `/worksheet/worksheet_answers_list`
List answers.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/worksheet/worksheet_answers_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"worksheetId": 1,
"pageNumber": 1,
"pageSize": 50
}'
```
## Worksheet groups
Form groups.
### `GET` `/worksheet_groups/worksheet_group_get`
Get group.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/worksheet_groups/worksheet_group_get" \
-H "X-API-Key: your-api-key" \
--data-urlencode "worksheetGroupId=1"
```
### `POST` `/worksheet_groups/worksheet_group_list`
List groups.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/worksheet_groups/worksheet_group_list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 50
}'
```
# Briefings
Source: https://docs.vh3.ai/api-reference/briefings
Pre-visit engineer briefings with full operational context
# Briefings
Generate a structured pre-visit briefing and call script for an engineer assigned to a job. Pulls job and customer context from the intelligence layer (regenerates the account summary when requested) and produces markdown briefing content plus a natural-language call opener.
Designed for `onTheWay` or `scheduled` job transitions.
## POST /briefing/generate
Generate an engineer briefing for a specific job.
**Request body:**
| Field | Type | Required | Description |
| -------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `job_id` | integer | Yes | Job to brief |
| `contact_id` | integer | Yes | Customer contact for the job |
| `force_regenerate_summary` | boolean | No | Bypass the cached customer summary and regenerate |
| `job_payload` | object | No | Raw job fallback when the job is not yet in the intelligence layer (ignored if the job already exists in the graph) |
**Response fields:**
| Field | Type | Description |
| ------------------ | ------ | ---------------------------------------------------------------------------- |
| `briefing` | string | Structured field service briefing (markdown) |
| `call_script` | string | Natural-language call opener for voice agents |
| `customer_summary` | string | Full customer analytical report used as context |
| `job_data` | object | Job reference, status, type, customer, engineer, planned times, site address |
| `resource_contact` | object | Engineer `mobile` and `email` from the graph |
| `parent_contact` | object | Parent customer `contact_id` and `name` when `HAS_PARENT` exists |
| `engineer_name` | string | Assigned engineer name |
| `generated_at` | string | ISO 8601 generation timestamp |
| `usage` | object | Token usage for AI generation |
**Example:**
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/briefing/generate" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"job_id": 12345,
"contact_id": 678
}'
```
**Use cases:**
* **Pre-visit pack:** Deliver site history, equipment context, and diagnostic precedents before arrival.
* **Voice briefing:** Feed `call_script` to an outbound call agent; send `briefing` via `POST /briefing/send-email` after the call.
* **Dispatcher assist:** Regenerate with `force_regenerate_summary: true` when account context has changed since the last visit.
**Notes:**
* Uses platform AI; subject to capacity limits (`503` with `Retry-After` when saturated).
* Returns `404` when the job or contact cannot be resolved.
* Typical latency 5–15s depending on summary cache hit.
# Cases
Source: https://docs.vh3.ai/api-reference/cases
Case management for multi-step operational workflows
# Cases
The Cases endpoints provide a lightweight case management system for tracking multi-step operational workflows, escalations, customer complaints, follow-up work, and anything that spans multiple jobs or interactions.
## POST /cases/create
Create a new case.
**Request body:**
| Field | Type | Required | Description |
| ------------- | ------- | -------- | ------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `title` | string | Yes | Case title |
| `type` | string | Yes | Case type (e.g. `escalation`, `complaint`, `follow_up`) |
| `description` | string | No | Detailed description |
| `priority` | string | No | Priority level (`low`, `medium`, `high`, `critical`) |
| `actor_type` | string | No | Who created the case (`user`, `system`, `automation`) |
| `actor_id` | integer | No | ID of the creating actor |
| `tags` | object | No | Tags for categorisation |
| `metadata` | object | No | Arbitrary metadata |
| `due_date` | number | No | Due date (unix timestamp) |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/cases/create" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"title": "Repeat boiler failure at Tesco Manchester",
"type": "escalation",
"priority": "high",
"description": "Third callout in 6 weeks for the same unit. Needs senior engineer assessment."
}'
```
***
## GET /cases/list
List cases with optional filtering.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------- | -------- | ---------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `status` | string | No | Filter by status |
| `type` | string | No | Filter by case type |
| `priority` | string | No | Filter by priority |
| `owner_id` | integer | No | Filter by case owner |
| `search` | string | No | Full-text search across case titles and descriptions |
| `page` | integer | No | Page number |
| `per_page` | integer | No | Results per page |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/cases/list" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "status=open" \
--data-urlencode "priority=high"
```
***
## GET /cases/search
Full-text search across all cases.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/cases/search" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "q=boiler Manchester"
```
***
## GET /cases/
Retrieve a specific case with full details.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/cases/case-001" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## PATCH /cases/
Update a case (title, description, priority, status, etc.).
```bash theme={null}
curl -X PATCH "https://api.vh3connect.io/api:kP8T1CK7/cases/case-001" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"priority": "critical"
}'
```
***
## POST /cases//transition
Transition a case to a new status.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/cases/case-001/transition" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"status": "resolved"
}'
```
***
## POST /cases//comments
Add a comment to a case.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/cases/case-001/comments" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"body": "Senior engineer booked for Friday. Parts on order."
}'
```
***
## GET /cases//activity
Retrieve the full activity timeline for a case, all updates, comments, transitions, and linked items.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/cases/case-001/activity" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## POST /cases//participants
Add a participant to a case.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/cases/case-001/participants" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"user_id": "user-42"
}'
```
***
## POST /cases//items
Link an item (job, contact, site) to a case.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/cases/case-001/items" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"item_type": "job",
"item_id": "12345"
}'
```
# Connie
Source: https://docs.vh3.ai/api-reference/connie
Conversational AI assistant with full operational context
# Connie
Connie is VH3 AI's conversational assistant. She has access to the full operational context (intelligence layer, semantic search, reports, and sentinel results) and responds to questions in natural language with cited, data-backed answers.
Capabilities, sessions, and how Connie uses the intelligence layer.
`toolCallOutputs`, usage, and verifying provenance in production UIs.
## POST /connie/chat
Send a message to Connie and receive a response grounded in your operational data.
**Request body:**
| Field | Type | Required | Description |
| ----------------------- | ------ | -------- | ---------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `message` | string | Yes | Your question or instruction |
| `session_id` | string | No | Session identifier for conversation continuity |
| `user_id` | string | No | Identifier for the user asking |
| `user_name` | string | No | Display name (personalises responses) |
| `user_company_name` | string | No | Company name for context |
| `summary` | string | No | Prior conversation summary (for long sessions) |
| `contact_id` | string | No | Scope to a specific customer context |
| `current_job_reference` | string | No | Job currently being discussed |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/connie/chat" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"message": "Which sites had the most repeat visits in the last 30 days?",
"session_id": "session-abc-123",
"user_name": "Sarah"
}'
```
**Example questions Connie can answer:**
* "Which engineers are consistently late on HVAC jobs?"
* "What is the repeat failure rate at Tesco sites?"
* "Has anyone seen this fault before?" (with a description)
* "Show me the top 5 customers by job volume this quarter"
* "What happened at the Manchester site last week?"
* "Give me a performance summary for engineer John Smith"
Connie maintains conversation context within a session. Follow-up questions like "What about last month?" reference the previous exchange automatically. Each response can include `toolCallOutputs` (structured results per tool) and `usage` (token counts). See [Agent observability](/guides/agent-observability).
***
## POST /connie/chat/voice
Send a voice interaction to Connie, designed for voice-first interfaces where the input is a transcribed audio message. Optimised for concise, text-to-speech-friendly responses.
**Request body:**
Same fields as `/connie/chat`.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/connie/chat/voice" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"message": "How many jobs did we complete yesterday?",
"session_id": "voice-session-001"
}'
```
***
## POST /connie/generate-summary
Generate an AI summary for a contact, useful for pre-call preparation or account review.
**Request body:**
| Field | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `contact_id` | string | Yes | Contact to summarise |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/connie/generate-summary" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"contact_id": "contact-789"
}'
```
***
## POST /connie/history/search
Search across past conversation history.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/connie/history/search" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "SLA breach discussion"
}'
```
***
## GET /connie/sessions
List chat sessions for a company.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/connie/sessions" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## GET /connie/sessions//messages
Retrieve all messages for a specific session.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/connie/sessions/session-abc-123/messages" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
# Contacts
Source: https://docs.vh3.ai/api-reference/contacts
Contact feed and detail lookup
# Contacts
The Contacts endpoints provide access to the people associated with your operation, engineers, customers, site contacts, and other stakeholders enriched from your FMS and connected systems.
## GET /contacts/feed
Returns a paginated feed of contacts for your company.
**Query parameters:**
| Param | Type | Required | Description |
| ------------------ | ------- | -------- | ------------------------------ |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `page_size` | integer | No | Results per page |
| `page_number` | integer | No | Page number |
| `q` | string | No | Search query (name, reference) |
| `contact_id` | string | No | Filter by specific contact |
| `reference` | string | No | Filter by contact reference |
| `contact_group_id` | string | No | Filter by contact group |
| `account_status` | string | No | Filter by account status |
| `compact` | boolean | No | Return compact response |
**Example:**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/contacts/feed" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "page_size=20" \
--data-urlencode "q=tesco"
```
***
## GET /contacts/
Returns the full contact record including associated jobs, sites, and AI-generated summary.
**Path parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------- |
| `contact_id` | string | Yes | The contact identifier |
**Query parameters:**
| Param | Type | Required | Description |
| ----------------- | ------- | -------- | ------------------------------------ |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `include_summary` | boolean | No | Include AI-generated contact summary |
| `compact` | boolean | No | Return compact response |
**Example:**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/contacts/456" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "include_summary=true"
```
# Dashboard
Source: https://docs.vh3.ai/api-reference/dashboard
Cached tenant business-health snapshot for KPI tiles
# Dashboard
Returns a cached, dashboard-ready snapshot of tenant operational health. Five sections (pipeline, performance, workforce, assets, and knowledge) map to dashboard KPI payloads. Near-zero AI cost at read time; aggregated from the intelligence layer.
## GET /dashboard
Tenant pulse snapshot.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------- | -------- | --------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `refresh` | boolean | No | Bypass cache and force a fresh snapshot (default `false`) |
**Response fields:**
| Field | Type | Description |
| ---------------------- | ------ | ------------------------------------------------------------------------------------- |
| `company_id` | string | Tenant identifier |
| `generated_at` | string | ISO 8601 snapshot time |
| `cached_until` | string | ISO 8601 cache expiry (5-minute TTL) |
| `sections.pipeline` | object | Job lifecycle: totals, active, unassigned, in progress, completions, status breakdown |
| `sections.performance` | object | Last 30 days: completion rate, first-visit-fix rate, avg start/end delta (minutes) |
| `sections.workforce` | object | Engineer counts, active today, avg jobs per engineer, top engineer |
| `sections.assets` | object | Customers, sites, vehicles, job types, job categories |
| `sections.knowledge` | object | Knowledge depth: intake records, outcomes, customer summaries, chat sessions |
**Example:**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/dashboard" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
Force refresh:
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/dashboard" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "refresh=true"
```
**Use cases:**
* **Home screen:** Single call to populate KPI tiles on first load.
* **Mobile summary:** Lightweight operational overview without running separate aggregate calls.
* **Health monitoring:** Internal or partner views of data coverage and knowledge-base completeness.
* **Scheduled snapshots:** n8n cron to archive pulse metrics for trend reporting.
**Notes:**
* Cached 5 minutes per tenant; uncached typically 200–800ms, cached under 10ms.
* Deterministic: the same underlying data yields the same metrics.
* Returns `502` if search or graph queries fail.
# Email Ingest
Source: https://docs.vh3.ai/api-reference/ingest
Extract structured job data from FM portal emails
# Email Ingest
Extract structured job fields from emails sent by known FM portals (Verisae, Bellrock, Access Maintain, Greene King, and tenant-specific overrides). Resolves customers, sites, and job types against the knowledge graph, evaluates confidence, and returns a review or auto-create outcome.
Use this endpoint when the sender domain is already identified as a portal. For unknown senders, use the general triage ingest path or classify first with `POST /triage/classify`.
## POST /ingest/email/portal
Portal ingest, structured extraction from a known FM portal email.
**Request body:**
| Field | Type | Required | Description |
| -------------------- | ------ | -------- | ------------------------------------------------------------------ |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant BigChange API key (verified against `company_id`) |
| `email_html` | string | Yes | HTML body of the email |
| `email_text` | string | No | Plain-text fallback when HTML is sparse |
| `email_subject` | string | No | Subject line |
| `email_from` | string | No | Sender address (used for portal detection) |
| `email_date` | string | No | Send time (ISO 8601) |
| `attachments` | array | No | Each item: `filename`, `content_base64`, `url`, `mime_type` |
| `preferred_type_ids` | array | No | Job type IDs to boost during classification (+0.05 when plausible) |
**Response fields:**
| Field | Type | Description |
| ----------------------- | ------- | ------------------------------------------------------------------------------------ |
| `status` | string | `auto_created`, `pending_review`, or `unprocessable` |
| `extraction` | object | Parsed work order fields and confidence |
| `resolution` | object | Matched `customers`, `sites`, `types`, `categories`, `parent_candidates` with scores |
| `reasoning` | string | Human-readable resolution summary |
| `job_created` | boolean | Whether a job was written to BigChange |
| `job_id` | integer | Created job ID when `job_created` is true |
| `extraction_id` | string | Pending-extraction UUID for review-queue flows |
| `review_flags` | array | Flags requiring human attention |
| `job_preview` | object | Dry-run BigChange payload when write-back is not yet live |
| `case_id` | string | Case management ID when a review case was created |
| `engineer_hints` | array | Ranked engineer suggestions from contact/type history |
| `job_options` | array | Selectable job drafts when status is `pending_review` |
| `recommended_option_id` | string | Suggested option from `job_options` |
| `surface` | string | Always `portal` for this endpoint |
**Example:**
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/ingest/email/portal" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"email_html": "",
"email_subject": "PureGym 449 Newhaven, Work Order 116222840",
"email_from": "noreply@verisae.com",
"email_date": "2026-04-18T10:00:00Z"
}'
```
**Use cases:**
* **FM portal automation:** Ingest Verisae, Bellrock, or other portal work orders without manual re-keying.
* **n8n inbound mail:** Trigger after `POST /triage/classify` returns `portal_ingest`, or when the sender domain is pre-filtered upstream.
* **Review queue:** When `status` is `pending_review`, use `extraction_id` with `POST /ingest/email/confirm` or `POST /ingest/email/reject`.
* **Quality evaluation:** Inspect `job_preview` and `resolution` scores before enabling auto-create to BigChange.
**Notes:**
* Uses platform AI for extraction; typical latency 3–10s.
* `api_key` is verified against your tenant credentials before any BigChange-facing step; mismatch returns `403`.
* Tenant settings (`portal_ingest_enabled`, `disabled_portals`, thresholds) gate behaviour without code changes.
# Jobs
Source: https://docs.vh3.ai/api-reference/jobs
Job feed, account job feed, and job details
# Jobs
The Jobs endpoints provide access to your enriched job records, including AI-extracted fault types, outcomes, timings, and relationships to engineers, sites, and customers.
## GET /jobs/feed
Returns a paginated feed of enriched jobs for your company. Supports filtering by entity, status, date range, and sort direction. All filters are optional and composable as AND conditions.
**Query parameters:**
| Param | Type | Required | Default | Description |
| ------------- | ------- | -------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `company_id` | string | Yes | - | Your tenant identifier |
| `api_key` | string | Yes | - | Your tenant API key |
| `page_size` | integer | No | 20 | Results per page (max 200) |
| `page_number` | integer | No | 1 | Page number (1-indexed) |
| `contact_id` | string | No | - | Filter by customer contact ID |
| `resource_id` | string | No | - | Filter by engineer/resource ID |
| `type_id` | string | No | - | Filter by job type ID |
| `category_id` | string | No | - | Filter by job category ID |
| `status` | string | No | - | Filter by status, single value or comma-separated (e.g. `completedOk,completedWithIssues`) |
| `result` | string | No | - | Filter by job result |
| `date_from` | string | No | - | ISO date/datetime, include jobs on or after (inclusive) |
| `date_to` | string | No | - | ISO date/datetime, exclude jobs on or after (exclusive) |
| `date_field` | string | No | `createdAt` | Which timestamp `date_from`/`date_to` apply to: `createdAt`, `plannedStartAt`, `plannedEndAt`, `actualStartAt`, `actualEndAt` |
| `direction` | string | No | `desc` | Sort direction on `createdAt`, `asc` or `desc` |
| `compact` | boolean | No | false | Strip nulls/empties to return a compact payload for AI agents |
**Example: completed jobs from May 2026**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/jobs/feed" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "page_size=20" \
--data-urlencode "status=completedOk,completedWithIssues" \
--data-urlencode "date_from=2026-05-01" \
--data-urlencode "date_to=2026-06-01" \
--data-urlencode "date_field=actualEndAt"
```
***
## GET /jobs/feed/account
Returns a paginated feed of jobs scoped to a **parent account and all its child contacts**. Pass any contact ID, parent or child, and the endpoint resolves the full hierarchy automatically.
This endpoint resolves the parent/child account hierarchy. If you pass a child contact ID, the parent is found and all sibling contacts are included. If you pass a parent, all children are included. Standalone contacts return only their own jobs.
**How hierarchy resolution works:**
| You pass | What happens |
| ----------------------- | -------------------------------------------------------- |
| A parent contact ID | Returns jobs for the parent + all child contacts |
| A child contact ID | Finds the parent, returns jobs for parent + all siblings |
| A standalone contact ID | Returns jobs for that contact only |
**Query parameters:**
| Param | Type | Required | Default | Description |
| ------------- | ------- | -------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `company_id` | string | Yes | - | Your tenant identifier |
| `api_key` | string | Yes | - | Your tenant API key |
| `contact_id` | string | Yes | - | Any contact ID in the account hierarchy (parent or child) |
| `page_size` | integer | No | 20 | Results per page (max 200) |
| `page_number` | integer | No | 1 | Page number (1-indexed) |
| `resource_id` | string | No | - | Filter by engineer/resource ID |
| `type_id` | string | No | - | Filter by job type ID |
| `category_id` | string | No | - | Filter by job category ID |
| `status` | string | No | - | Filter by status, single value or comma-separated (e.g. `completedOk,completedWithIssues`) |
| `result` | string | No | - | Filter by job result |
| `date_from` | string | No | - | ISO date/datetime, include jobs on or after (inclusive) |
| `date_to` | string | No | - | ISO date/datetime, exclude jobs on or after (exclusive) |
| `date_field` | string | No | `createdAt` | Which timestamp `date_from`/`date_to` apply to: `createdAt`, `plannedStartAt`, `plannedEndAt`, `actualStartAt`, `actualEndAt` |
| `direction` | string | No | `desc` | Sort direction on `createdAt`, `asc` or `desc` |
| `compact` | boolean | No | false | Strip nulls/empties to return a compact payload for AI agents |
**Response** includes an `account` block with the resolved hierarchy context:
```json theme={null}
{
"account": {
"parentContactId": 1234,
"parentName": "Whitbread PLC",
"parentReference": "W140",
"childCount": 462,
"contactIds": [1234, 5678, 5679, "..."],
"contactGroup": "Parent - Agreed rates"
},
"jobs": ["..."],
"page": 1,
"pageSize": 25,
"totalJobs": 312,
"totalPages": 13
}
```
**Example: all completed jobs for an account in Q1 2026**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/jobs/feed/account" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "contact_id=5589521" \
--data-urlencode "status=completedOk,completedWithIssues" \
--data-urlencode "date_from=2026-01-01" \
--data-urlencode "date_to=2026-04-01" \
--data-urlencode "page_size=50"
```
**Use cases:**
* **Monthly account reviews**, scope by `date_from`/`date_to` with `date_field=actualEndAt` to see all work delivered to a customer account in a period.
* **Account + type filtering**, add `type_id` to see only fire alarm or HVAC jobs across the whole account hierarchy.
* **Account performance**, combine with `status=completedOk,completedWithIssues` to measure first-visit fix rate across all child sites.
***
## GET /jobs/
Returns the full enriched record for a specific job, including AI-extracted fields, linked relationships from the intelligence layer, and timing data.
**Path parameters:**
| Param | Type | Required | Description |
| -------- | ------ | -------- | ------------------ |
| `job_id` | string | Yes | The job identifier |
**Query parameters:**
| Param | Type | Required | Description |
| -------------------- | ------- | -------- | ----------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `include_worksheets` | boolean | No | Include worksheet data |
| `compact` | boolean | No | Return compact response |
**Example:**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/jobs/12345" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "include_worksheets=true"
```
***
## POST /aggregate/jobs
Job metrics with groupBy dimensions and period comparison, powers dashboard charts and trend analysis.
**Request body:**
| Field | Type | Required | Description |
| ------------ | ------- | -------- | --------------------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `metric` | string | Yes | Metric to compute (e.g. `count`, `sla_punctuality`, `first_time_fix`) |
| `time_axis` | string | No | Time bucketing (`day`, `week`, `month`) |
| `period` | string | No | Period to analyse (e.g. `last_30_days`, `last_quarter`) |
| `compare_to` | string | No | Comparison period (e.g. `previous_period`) |
| `group_by` | string | No | Dimension to group by (`engineer`, `customer`, `job_type`, `site`) |
| `filters` | object | No | Additional filters |
| `limit` | integer | No | Max groups to return |
**Example:**
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/aggregate/jobs" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"metric": "count",
"time_axis": "week",
"period": "last_30_days",
"group_by": "engineer"
}'
```
# VH3 AI Intelligence
Source: https://docs.vh3.ai/api-reference/overview
Semantic search, relationship-aware intelligence, Connie, sentinels, reports, and email triage
# VH3 AI Intelligence
The intelligence layer exposes enriched operational data, semantic search, proactive sentinels, reports, Connie, and email triage. Every endpoint requires `company_id` and `api_key`.
For direct BigChange read/write (jobs, contacts, invoices, stock), use the separate [BigChange API](/api-reference/bigchange/overview), same API key, `X-API-Key` header only.
## Base URL
```
https://api.vh3connect.io/api:kP8T1CK7
```
## Authentication
Pass `company_id` and `api_key` on every request. POST: JSON body. GET: query parameters.
See [Authentication](/authentication) for the full two-API comparison and User Auth (JWT).
## Endpoint groups
| Group | Description |
| ------------------------------------- | -------------------------------------------------------------------------------- |
| [Search](/api-reference/search) | Semantic search, autocomplete, enriched outcomes, customer summary sections |
| [Jobs](/api-reference/jobs) | Job feed, job details, and aggregation |
| [Contacts](/api-reference/contacts) | Contact feed and contact detail lookup |
| [Dashboard](/api-reference/dashboard) | Cached tenant KPI snapshot (pipeline, performance, workforce, assets, knowledge) |
| [Sentinels](/api-reference/sentinels) | Run and query proactive sentinel monitors |
| [Reports](/api-reference/reports) | Generate daily, weekly, and account-level reports |
| [Briefings](/api-reference/briefings) | Pre-visit engineer briefings and call scripts |
| [Weather](/api-reference/weather) | Forecast, historical, and graph-resolved weather |
| [Email Triage](/api-reference/triage) | Classify inbound emails |
| [Email Ingest](/api-reference/ingest) | Extract structured data from FM portal emails |
| [Connie](/api-reference/connie) | Conversational AI with cited answers |
| [Cases](/api-reference/cases) | Case management |
| [Teams](/api-reference/teams) | Team management and access scoping |
## Request format
### POST endpoints
```json theme={null}
{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "boiler fault",
"limit": 10
}
```
### GET endpoints
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/jobs/feed" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
## Error format
```json theme={null}
{
"code": "ERROR_CODE_INPUT_ERROR",
"message": "Missing param: company_id",
"payload": {
"param": "company_id"
}
}
```
| Status code | Meaning |
| ----------- | ----------------------------------------------------- |
| `400` | Bad request, missing or invalid parameters |
| `401` | Unauthorised, invalid API key |
| `404` | Not found, resource does not exist for your tenant |
| `409` | Conflict, a task is already running for this resource |
| `422` | Validation error |
| `429` | Rate limited |
| `500` | Server error |
## Task-based endpoints
Long-running operations return a `task_id` immediately. Poll the status endpoint until complete.
Possible statuses: `pending`, `running`, `completed`, `failed`, `cancelled`.
# Reports
Source: https://docs.vh3.ai/api-reference/reports
Automated operational reporting
# Reports
The Reports endpoints let you generate automated operational reports. Eight report types are available, covering daily operations, weekly summaries, and account-level performance analysis.
## Report types
| Type | Description |
| ----------------------- | ------------------------------------------------------------ |
| `daily_operations` | Daily job completions, SLA performance, and notable events |
| `weekly_summary` | Weekly trends, engineer rankings, and operational highlights |
| `account_monthly` | Per-customer monthly performance report |
| `executive_health` | Five-dimension health check across up to 3 years of history |
| `engineer_performance` | Individual engineer performance breakdown |
| `site_health` | Site-level fault and maintenance trends |
| `customer_intelligence` | Customer relationship and risk summary |
| `sentinel_digest` | Summary of all sentinel triggers in period |
## POST /reports/generate
Trigger generation of a report.
**Request body:**
| Field | Type | Required | Description |
| ------------------- | ------- | -------- | -------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `report_type` | string | Yes | Report type identifier (from table above) |
| `sections` | array | No | Specific sections to include (omit for all) |
| `date` | string | No | Report date (YYYY-MM-DD) |
| `include_narrative` | boolean | No | Include AI-generated narrative text |
| `contact_id` | integer | No | Scope to a specific customer (for account reports) |
| `month` | string | No | Month to report on (YYYY-MM) |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/reports/generate" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"report_type": "weekly_summary",
"date": "2024-11-10",
"include_narrative": true
}'
```
***
## GET /reports/sections
Returns available report sections and their metadata.
**Query parameters:**
| Param | Type | Required | Description |
| ------------- | ------ | -------- | ------------------------------ |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `report_type` | string | No | Filter sections by report type |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/reports/sections" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "report_type=weekly_summary"
```
# Search
Source: https://docs.vh3.ai/api-reference/search
Semantic and keyword search across your operational history
# Search
The Search endpoints let you find relevant past jobs, outcomes, and intake records by describing what you're looking for in natural language. The platform uses hybrid search, combining meaning-based matching with keyword retrieval, to surface relevant results even when terminology differs.
## POST /search/outcomes
Search across AI-enriched job outcomes. This is the primary search endpoint for finding jobs by what happened, what was done, or what the result was.
**Request body:**
| Field | Type | Required | Description |
| ------------- | ------- | -------- | -------------------------------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `query_text` | string | Yes | Natural language search query |
| `limit` | integer | No | Max results to return (default: 10) |
| `type_id` | string | No | Filter by job type |
| `category_id` | string | No | Filter by job category |
| `resource_id` | string | No | Filter by engineer/resource |
| `contact_id` | string | No | Filter by customer (contact). Preferred scope for account-level precedent search |
| `cleanup` | boolean | No | Whether to clean the results metadata |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/outcomes" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "air conditioning unit not cooling",
"limit": 5
}'
```
***
## POST /search/outcomes/enriched
Semantic search over job outcomes with relationship enrichment from the intelligence layer. Same request body and filters as `POST /search/outcomes`. Adds `related_works` grouped by job type, engineer, and site for each hit set.
**Request body:**
| Field | Type | Required | Description |
| -------------- | ------- | -------- | ------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `query_text` | string | Yes | Natural language search query (3–2000 characters) |
| `limit` | integer | No | Max results (default 10, max 100) |
| `type_id` | integer | No | Filter by job type |
| `category_id` | integer | No | Filter by job category |
| `job_group_id` | integer | No | Filter by job group |
| `vertical` | string | No | Filter by AI-classified vertical |
| `sub_vertical` | string | No | Filter by AI-classified sub-vertical |
| `resource_id` | integer | No | Filter by engineer |
| `contact_id` | integer | No | Filter by customer contact |
| `site_key` | string | No | Filter by site |
| `start_date` | string | No | Lower bound on `actual_start_at` (`YYYY-MM-DD`) |
| `end_date` | string | No | Upper bound on `actual_start_at` (`YYYY-MM-DD`) |
| `status` | string | No | Filter by job status |
| `result` | string | No | Filter by job result |
**Response fields:**
| Field | Type | Description |
| --------------- | ------- | ----------------------------------------------------------------------------------------- |
| `hits` | array | Slim outcome hits (`job_id`, `job_ref`, `score`, `contact_id`, `status`, `summary`, etc.) |
| `count` | integer | Number of hits |
| `related_works` | object | `by_type`, `by_engineer`, `by_site` aggregates derived from the hit set |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/outcomes/enriched" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "replaced PCB on Vaillant ecoTEC, F28 fault cleared",
"limit": 10,
"contact_id": 12345
}'
```
**Use cases:**
* **Fault resolution:** Find similar past fixes and see completion patterns for that job type.
* **Engineer fit:** Check whether engineers on matched outcomes have history with the customer or fault class.
* **Site risk:** Surface repeat failures at the site alongside semantically similar outcomes.
**Notes:**
* Slower than `/search/outcomes` due to relationship enrichment (\~500ms–1s additional).
* `related_works` keys are derived from returned hits only, not the full matching corpus.
* Returns `502` if semantic search or enrichment fails.
***
## POST /search/intake
Search across raw job intake text, the original fault descriptions as entered by dispatchers or customers.
**Request body:**
| Field | Type | Required | Description |
| ------------ | ------- | -------- | ----------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `query_text` | string | Yes | Natural language search query |
| `limit` | integer | No | Max results to return (default: 10) |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/intake" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "heating system tripping",
"limit": 5
}'
```
***
## POST /search/intake/enriched
Semantic search over job intake text with relationship enrichment, returns richer context by joining linked records to each result.
**Request body:**
| Field | Type | Required | Description |
| ------------ | ------- | -------- | ----------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `query_text` | string | Yes | Natural language search query |
| `limit` | integer | No | Max results to return |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/intake/enriched" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "fire alarm fault",
"limit": 5
}'
```
***
## GET /search/autocomplete
Fuzzy / phonetic / email-aware lookup across contacts, persons (site contacts
and account holders), engineers, jobs, and taxonomy entities. Returns results
grouped by entity type plus a flat `results[]` array for back-compat.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `q` | string | Yes | Search text, name, postcode, email address, UUID personId, phone, reference, or numeric id |
| `limit` | integer | No | Max results per group (default 10, max 50) |
| `types` | string | No | Comma-separated filter. Allowed: `contact`, `person`, `engineer`, `job`, `job_type`, `job_category`, `contact_group`, `resource_group` |
**Search capabilities:**
* **Name / phonetic:** `Smyth` finds `Smith`; `PureGym` finds `Pure Gym`
* **Email:** type a full or partial email (`ric@vezzahub.com`, `ric@`) to
find the matching person directly. Results carry `matchedVia: "email"`.
* **UUID / personId:** paste a standard UUID to resolve the person directly
via their `ids` array. Returns `matchedVia: "person_id"` with score 1.0.
* **Postcode:** UK postcodes with or without a space (`NN10 5AB` / `NN105AB`)
* **Reference:** job reference or order number prefix
* **Numeric id:** bare integer resolves `contactId`, `resourceId`, or `jobId`
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/search/autocomplete" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "q=ric@vezzahub.com" \
--data-urlencode "limit=10"
```
The response groups results under `groups.contacts`, `groups.people`,
`groups.engineers`, `groups.jobs`, `groups.jobTypes`, `groups.jobCategories`,
`groups.contactGroups`, and `groups.resourceGroups`. Each result includes a
`matchedVia` field indicating why it was returned (`name`, `email`,
`person_id`, `postcode`, `phonetic`, `reference`, `id`, `site_bridge`, etc.).
**Use cases:**
* **Typeahead UI:** Power customer, site, and job pickers in dispatch or ingest review screens.
* **Email entity resolution:** Resolve portal payloads to `contact_id` and `site_key` before `POST /ingest/email/portal`.
* **Connie grounding:** Disambiguate names or postcodes before semantic search or graph queries.
**Notes:**
* Minimum query length is 2 characters. Accepts any entity Id such as contact, job, job\_group\_id, reference, resource etc
* Use `GET /search/autocomplete/diagnose` when all groups return empty (index health).
***
## GET /search/autocomplete/diagnose
Health check for the autocomplete index pipeline (always returns 200; inspect `missing`, `populating`, `advice`).
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/search/autocomplete/diagnose" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## POST /search/summary-sections
Hybrid search across **Customer Summary** knowledge sections. Each customer can have up to seven modular sections (overview, job history, equipment, analyses, performance, communication, risk). Each section is indexed independently so you can search one dimension or all of them. Results are ranked without an LLM call.
**Request body:**
| Field | Type | Required | Description |
| ------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `query_text` | string | Yes | Natural language search query |
| `section_key` | string | No | Limit to one section. Allowed: `customer_overview`, `job_history_patterns`, `systems_equipment`, `key_analyses`, `operational_performance`, `communication_summary`, `risk_opportunity` |
| `contact_id` | string | No | Scope to one customer |
| `limit` | integer | No | Max results (default: 10) |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/summary-sections" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "recurring boiler issues on PPM contracts",
"section_key": "risk_opportunity",
"limit": 5
}'
```
***
## GET /search/summary-sections/by-contact//
Return the full stored Customer Summary for one contact (all sections). Use when you need the complete account brief in a single call rather than a ranked search.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/search/summary-sections/by-contact/your-company-id/your-contact-id" \
--data-urlencode "api_key=your-api-key"
```
Summaries are generated from the operational graph and refreshed incrementally by the account summary pipeline. See [Operational discovery](/guides/operational-discovery) for how summaries stay current in Connie sessions.
Incremental refresh endpoint: `POST /backfill/summary-kb` (tenant-authenticated; same `company_id` + `api_key` envelope).
# Sentinels
Source: https://docs.vh3.ai/api-reference/sentinels
Proactive operational and growth opportunity monitoring
# Sentinels
Sentinels are proactive monitors that continuously watch your operational data for emerging risks and revenue opportunities. They run as structured reads on the operational graph with near-zero AI cost at detection. Thresholds, exclusion filters, and result limits are all configurable per tenant.
See `GET /sentinels/registry` for active sentinel IDs and current defaults.
Implementation notes (May 2026):
* For `repeat_failure_escalation`, `customer_risk_escalation`, and `customer_noncomplete_anomaly`, "non-complete" is derived from `Job.status = completedWithIssues` (not `JobResult` labels).
* In `customer_risk_escalation`, late finishes are counted only when `endDeltaMins > 0` (strictly late).
* In `engineer_performance_slip`, `evidence.recentJobs` contains the jobs that formed the triggering streak, and `evidence.latestJobs` provides the latest context.
* Treat `GET /sentinels/registry` as the source of truth for active sentinel IDs and defaults.
## Sentinel types
### Operational (13 sentinels)
| Sentinel | What it detects |
| ---------------------------- | ----------------------------------------------------------------- |
| `engineer_performance_slip` | Engineers whose completion rates or SLA punctuality have degraded |
| `site_deterioration` | Sites with increasing fault frequency or repeat visits |
| `sla_breach_cluster` | Concentrated SLA breaches by geography, engineer, or customer |
| `scheduling_drift` | Growing gaps between job creation and completion |
| `repeat_visit_spike` | Abnormal repeat visit rates for specific job types or sites |
| `first_time_fix_decline` | Drop in first-time-fix rates by engineer or job category |
| `response_time_degradation` | Increasing time between job raised and first attendance |
| `workload_imbalance` | Uneven job distribution across engineers |
| `completion_rate_drop` | Falling job completion rates |
| `customer_complaint_pattern` | Emerging complaint clusters |
| `equipment_failure_trend` | Recurring equipment failures at specific sites |
| `certification_gap` | Engineers approaching or past certification expiry |
| `data_quality_alert` | Missing or inconsistent data in recent job records |
### Growth opportunity (6 sentinels)
| Sentinel | What it detects |
| ---------------------------- | -------------------------------------------------------------------- |
| `dormant_customer` | Customers with no recent activity who may be ready for re-engagement |
| `overdue_service_interval` | Equipment or sites past their recommended service interval |
| `single_service_cross_sell` | Customers using only one service line, cross-sell candidates |
| `engineer_flagged_follow_up` | Follow-on work flagged by engineers in job notes |
| `seasonal_buying_pattern` | Historical patterns suggesting upcoming demand |
| `geographic_upsell_cluster` | Concentration of existing customers near prospects |
## POST /sentinels/run
Execute one or more sentinels against your data and return current results.
**Request body:**
| Field | Type | Required | Description |
| -------------- | ------ | -------- | ------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `sentinel_ids` | object | No | Specific sentinels to run (omit to run all) |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/sentinels/run" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"sentinel_ids": ["site_deterioration", "engineer_performance_slip"]
}'
```
To run all sentinels, omit `sentinel_ids`:
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/sentinels/run" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key"
}'
```
***
## POST /sentinels/run/
Run a single named sentinel.
**Path parameters:**
| Param | Type | Required | Description |
| ------------- | ------ | -------- | --------------------------------------- |
| `sentinel_id` | string | Yes | Sentinel identifier (from tables above) |
**Request body:**
| Field | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/sentinels/run/dormant_customer" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key"
}'
```
***
## GET /sentinels/registry
Returns all available sentinel definitions and their configuration.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/sentinels/registry" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## GET /sentinels/results
Returns the latest cached sentinel results for your tenant.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/sentinels/results" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
# Teams
Source: https://docs.vh3.ai/api-reference/teams
Team management, membership, and entity scoping
# Teams
The Teams endpoints manage organisational teams, groups of users that can be scoped to specific customers, sites, or other entities. Teams enable access control and filtered views across the platform.
## GET /teams/list
List all teams for your company.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------- | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `purpose` | string | No | Filter by team purpose |
| `search` | string | No | Search by team name |
| `page` | integer | No | Page number |
| `per_page` | integer | No | Results per page |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/teams/list" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## POST /teams/create
Create a new team.
**Request body:**
| Field | Type | Required | Description |
| ------------- | ------- | -------- | --------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `name` | string | Yes | Team name |
| `description` | string | No | Team description |
| `purpose` | string | No | Team purpose/category |
| `metadata` | object | No | Arbitrary metadata |
| `actor_type` | string | No | Who created the team (`user`, `system`) |
| `actor_id` | integer | No | ID of the creating actor |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/teams/create" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"name": "North Region",
"description": "Engineers and accounts in the northern region"
}'
```
***
## GET /teams/
Retrieve a specific team with its members and linked entities.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/teams/team-001" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## PATCH /teams/
Update team details.
**Request body:**
| Field | Type | Required | Description |
| ------------- | ------- | -------- | ------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `name` | string | No | New team name |
| `description` | string | No | Updated description |
| `purpose` | string | No | Updated purpose |
| `metadata` | object | No | Updated metadata |
| `is_active` | boolean | No | Activate or deactivate the team |
```bash theme={null}
curl -X PATCH "https://api.vh3connect.io/api:kP8T1CK7/teams/team-001" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"name": "North Region, HVAC"
}'
```
***
## GET /teams//members
List all members of a team.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/teams/team-001/members" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## POST /teams//members
Add a member to a team.
**Request body:**
| Field | Type | Required | Description |
| ----------------- | ------- | -------- | ------------------------------------ |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `user_id` | integer | Yes | User to add |
| `role` | string | Yes | Role within team (`member`, `admin`) |
| `is_default_team` | boolean | No | Set as default team for this user |
| `actor_type` | string | No | Who performed the action |
| `actor_id` | integer | No | ID of the acting user |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/teams/team-001/members" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"user_id": 42,
"role": "member"
}'
```
***
## DELETE /teams//members/
Remove a member from a team.
```bash theme={null}
curl -X DELETE "https://api.vh3connect.io/api:kP8T1CK7/teams/team-001/members/membership-99" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key"
}'
```
***
## GET /teams//entities
List all entities linked to a team.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `type` | string | No | Filter by entity type |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/teams/team-001/entities" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## POST /teams//entities
Link an entity (customer, site, job type) to a team.
**Request body:**
| Field | Type | Required | Description |
| ------------- | ------- | -------- | ------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `entity_type` | string | Yes | Entity type (e.g. `customer`, `site`, `job_type`) |
| `entity_id` | string | Yes | Entity identifier |
| `label` | string | No | Display label for this link |
| `context` | string | No | Additional context |
| `metadata` | object | No | Arbitrary metadata |
| `actor_type` | string | No | Who performed the action |
| `actor_id` | integer | No | ID of the acting user |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/teams/team-001/entities" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"entity_type": "customer",
"entity_id": "contact-456"
}'
```
***
## DELETE /teams//entities/
Unlink an entity from a team.
```bash theme={null}
curl -X DELETE "https://api.vh3connect.io/api:kP8T1CK7/teams/team-001/entities/link-77" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key"
}'
```
***
## GET /teams/search
Search teams by name or description.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------- | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `q` | string | Yes | Search term |
| `page` | integer | No | Page number |
| `per_page` | integer | No | Results per page |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/teams/search" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "q=north region"
```
***
## GET /entities///teams
Find which teams a given entity belongs to (reverse lookup).
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/entities/customer/contact-456/teams" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
***
## GET /users//teams
Get all teams a specific user belongs to.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/users/42/teams" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
# Email Triage
Source: https://docs.vh3.ai/api-reference/triage
Classify inbound emails by category, urgency, and routing action
# Email Triage
Classify inbound emails against your tenant taxonomy. Returns category, urgency, sentiment, and a deterministic routing decision. Known FM portal senders can short-circuit to `portal_ingest` without AI classification.
## POST /triage/classify
Classify a single email.
**Request body:**
| Field | Type | Required | Description |
| ------------------- | ------- | -------- | --------------------------------------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `body` | string | Yes | Email body (plaintext or stripped HTML) |
| `subject` | string | No | Email subject line |
| `sender_address` | string | Yes | Sender email address |
| `sender_name` | string | No | Sender display name |
| `timestamp` | string | No | ISO 8601 send time |
| `attachments` | array | No | Attachment metadata (`filename`, `mime_type`, `size_bytes`) |
| `is_reply` | boolean | No | Email is a reply (default `false`) |
| `is_forward` | boolean | No | Email is a forward (default `false`) |
| `source_ref` | string | No | External message ID for deduplication |
| `skip_portal_check` | boolean | No | Skip portal sender detection when the caller has already routed portal traffic upstream |
**Response fields:**
| Field | Type | Description |
| ------------------------------------ | ------- | ------------------------------------------------------------------ |
| `classification.category` | string | Taxonomy category code |
| `classification.category_confidence` | number | Category confidence (0–1) |
| `classification.urgency` | string | `emergency`, `urgent`, `standard`, or `low` |
| `classification.sentiment` | string | `frustrated`, `neutral`, or `positive` |
| `classification.safety_override` | boolean | H\&S language forced a safety category |
| `classification.is_follow_up` | boolean | Repeated chase or escalation |
| `classification.reasoning` | string | Classification rationale |
| `decision.action` | string | `route`, `archive`, `priority_alert`, or `portal_ingest` |
| `decision.destination` | string | Target queue or team |
| `decision.priority` | boolean | Elevated attention required |
| `decision.flags` | array | Routing flags (e.g. `cs_attention`, `urgency_bumped`) |
| `decision.reasoning` | string | Routing rationale |
| `portal_match` | string | Matched portal ID when sender is a known FM portal; otherwise null |
| `pre_filter_hit` | boolean | Caught as noise without AI classification |
| `processed_at` | string | ISO 8601 processing timestamp |
**Example:**
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/triage/classify" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"subject": "RE: Cabin delivery for site WX-4821",
"body": "We need to change the delivery date for the cabin order.",
"sender_address": "john@contractor.example.com",
"sender_name": "John Smith",
"timestamp": "2026-03-05T10:30:00Z",
"is_reply": true
}'
```
**Use cases:**
* **Inbox routing:** Branch n8n or helpdesk workflows on `decision.action` and `decision.destination` before human review.
* **Portal handoff:** When `decision.action` is `portal_ingest`, forward the message to `POST /ingest/email/portal` instead of a generic queue.
* **Priority escalation:** Filter on `classification.urgency` and `decision.priority` for same-day handling.
* **Volume analytics:** Aggregate `classification.category` counts to measure inbound mix by type.
**Notes:**
* Pipeline order: portal short-circuit → pre-filter → AI classification → rule-based routing.
* Pass `skip_portal_check: true` when upstream logic has already separated portal traffic.
* Typical latency: instant for portal/pre-filter hits; 2–5s when AI classification runs.
* Use `GET /triage/categories` to fetch the active taxonomy for UI pickers.
***
## GET /triage/categories
Return the category taxonomy for UI rendering (system default plus tenant overlay).
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------------------------------- |
| `company_id` | string | No | Tenant scope; omit for system default taxonomy |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/triage/categories" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
**Response:** `categories[]` with `value` (category code), `label`, and `description`.
# User Authentication (JWT)
Source: https://docs.vh3.ai/api-reference/user-auth
Per-user login and JWT session management for interactive applications built on VH3
# User Authentication (JWT)
These endpoints provide per-user login and JWT session management for **interactive applications:** custom front-ends, customer portals, and embedded tools where individual users need to sign in and maintain a session.
**Base URL:** `https://api.vh3connect.io/api:lBQnyyZL`
Login requires only `email` and `password`. The user's tenant is resolved server-side. After login, every call uses `Authorization: Bearer `, no API key is ever sent from the client.
Need to manage users from a back-end script or integration (no user session)? Use the [Users](/api-reference/users) endpoints on the main FSI API with `company_id` + `api_key`. Those endpoints are **server-side only:** the API key must never appear in client-side code.
***
## POST /auth/login
Authenticate a user with email and password. Returns a JWT token valid for 24 hours. The user's tenant is resolved server-side from their account, no API key is required from the client.
**Request body:**
| Field | Type | Required | Description |
| ---------- | ------ | -------- | ------------------ |
| `email` | email | Yes | User email address |
| `password` | string | Yes | User password |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:lBQnyyZL/auth/login" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword"
}'
```
**Response:**
```json theme={null}
{
"authToken": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0..."
}
```
**Error responses:**
| Status | Error | Cause |
| ------ | --------------------------- | ------------------------------------------------ |
| `401` | `Invalid email or password` | Wrong email, wrong password, or no account found |
| `401` | `Account is deactivated` | User has been archived |
***
## POST /auth/refresh
Refresh an expiring JWT token. Returns a new token with a fresh 24-hour expiry.
**Headers:**
| Header | Value |
| --------------- | ---------------- |
| `Authorization` | `Bearer ` |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:lBQnyyZL/auth/refresh" \
-H "Authorization: Bearer eyJhbGciOi..."
```
**Response:**
```json theme={null}
{
"authToken": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0..."
}
```
***
## GET /auth/me
Get the current user profile from the JWT token. Includes the user's company information.
**Headers:**
| Header | Value |
| --------------- | ---------------- |
| `Authorization` | `Bearer ` |
```bash theme={null}
curl "https://api.vh3connect.io/api:lBQnyyZL/auth/me" \
-H "Authorization: Bearer eyJhbGciOi..."
```
**Response:**
```json theme={null}
{
"id": 42,
"first_name": "Jane",
"last_name": "Smith",
"company_id": "abc-123-def",
"email": "jane@example.com",
"role": "admin",
"phone": null,
"profile_picture": { "url": null },
"_company": {
"id": "abc-123-def",
"name": "Acme Field Services"
}
}
```
***
## POST /users/invite
Invite a new user by email to the authenticated user's company. Returns an invitation token valid for 7 days. **Requires `admin` or `developer` role.**
**Headers:**
| Header | Value |
| --------------- | ---------------- |
| `Authorization` | `Bearer ` |
**Request body:**
| Field | Type | Required | Default | Description |
| ------------ | ------ | -------- | ---------- | ---------------------------------------------------------- |
| `email` | email | Yes | None | Email address to invite |
| `role` | string | No | `standard` | Role to assign: `admin`, `manager`, `standard`, `engineer` |
| `first_name` | string | No | None | First name of the invited user |
| `last_name` | string | No | None | Last name of the invited user |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:lBQnyyZL/users/invite" \
-H "Authorization: Bearer eyJhbGciOi..." \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"role": "standard",
"first_name": "John",
"last_name": "Doe"
}'
```
**Response:**
```json theme={null}
{
"email": "newuser@example.com",
"role": "standard",
"invite_token": "eyJhbGciOi...",
"expires_in": 604800
}
```
**Error responses:**
| Status | Error | Cause |
| ------ | --------------------------------------- | -------------------------------------- |
| `401` | `Only admin users can invite new users` | Requesting user is not admin/developer |
| `400` | `A user with this email already exists` | Duplicate email |
***
## GET /users/list
List all active users belonging to the authenticated user's company. Supports pagination. **Requires `admin` or `developer` role.**
**Headers:**
| Header | Value |
| --------------- | ---------------- |
| `Authorization` | `Bearer ` |
**Query parameters:**
| Param | Type | Required | Default | Description |
| ---------- | ------- | -------- | ------- | -------------- |
| `page` | integer | No | `1` | Page number |
| `per_page` | integer | No | `25` | Items per page |
```bash theme={null}
curl "https://api.vh3connect.io/api:lBQnyyZL/users/list?page=1&per_page=25" \
-H "Authorization: Bearer eyJhbGciOi..."
```
**Response:**
```json theme={null}
{
"items": [
{
"id": 42,
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"role": "admin",
"phone": null,
"profile_picture": { "url": null },
"email_verified": true
},
{
"id": 43,
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"role": "standard",
"phone": null,
"profile_picture": { "url": null },
"email_verified": true
}
],
"curPage": 1,
"nextPage": null,
"prevPage": null
}
```
***
## DELETE /users/
Soft-delete a user by setting their account to archived. The user will no longer be able to log in. Cannot delete your own account. **Requires `admin` or `developer` role.**
**Headers:**
| Header | Value |
| --------------- | ---------------- |
| `Authorization` | `Bearer ` |
**Path parameters:**
| Param | Type | Description |
| --------- | ------- | ------------------------ |
| `user_id` | integer | ID of the user to delete |
```bash theme={null}
curl -X DELETE "https://api.vh3connect.io/api:lBQnyyZL/users/43" \
-H "Authorization: Bearer eyJhbGciOi..."
```
**Response:**
```json theme={null}
{
"success": true,
"user_id": 43
}
```
**Error responses:**
| Status | Error | Cause |
| ------ | ------------------------------------------ | ----------------------------------------- |
| `401` | `Only admin users can delete users` | Requesting user is not admin/developer |
| `400` | `Cannot delete your own account` | `user_id` matches the authenticated user |
| `400` | `User not found` | No user with this ID |
| `401` | `Cannot delete users from another company` | Target user belongs to a different tenant |
***
## Roles reference
| Role | Data access | User management |
| ----------- | ----------- | -------------------------- |
| `admin` | Full | Invite, list, delete users |
| `developer` | Full | Invite, list, delete users |
| `manager` | Full | No |
| `standard` | Full | No |
| `engineer` | Full | No |
# Users
Source: https://docs.vh3.ai/api-reference/users
User management, list, invite, update roles, and remove users from your company
# Users
The Users endpoints manage the team members associated with your company. They use the standard `company_id` + `api_key` authentication, the same as all other VH3 AI endpoints.
**Base URL:** `https://api.vh3connect.io/api:kP8T1CK7`
These endpoints are **server-side only**. The `api_key` must never be sent from a browser, mobile app, or any client-side code. If you are building an interactive front-end, use the [User Authentication (JWT)](/api-reference/user-auth) endpoints instead, your users log in once and every subsequent call uses a Bearer token, with no API key in the browser.
***
## GET /users/list
List all active (non-archived) users for your company.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/users/list" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
**Response:**
```json theme={null}
[
{
"id": 42,
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"username": "jsmith",
"role": "admin",
"profile_picture": { "url": null }
},
{
"id": 43,
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"username": "jdoe",
"role": "standard",
"profile_picture": { "url": null }
}
]
```
***
## GET /users/invites
List pending (not yet accepted) invitations for your company.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/users/invites" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
**Response:**
```json theme={null}
[
{
"id": "uuid-token-id",
"company_id": "your-company-id",
"email": "newuser@example.com",
"role": "standard",
"created_at": "2026-05-17T19:57:00Z",
"expires_at": "2026-06-17T19:57:00Z",
"accepted_at": null
}
]
```
***
## POST /users/invite
Invite a user to your company by email. Sends an invitation email via SendGrid with an accept link. If the email address already exists in the system without a company, they are immediately linked to your company.
**Request body:**
| Field | Type | Required | Description |
| -------------- | ------ | -------- | -------------------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `email` | email | Yes | Email address to invite |
| `role` | string | Yes | Role to assign: `admin`, `manager`, `standard`, `engineer` |
| `company_name` | string | Yes | Your company display name, shown in the invitation email |
| `inviter_name` | string | Yes | Name of the person sending the invite, shown in the invitation email |
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/users/invite" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"email": "newuser@example.com",
"role": "standard",
"company_name": "Acme Field Services",
"inviter_name": "Jane Smith"
}'
```
**Response:**
```json theme={null}
{
"success": true,
"message": "Invitation sent to newuser@example.com"
}
```
**Error responses:**
| Status | Error | Cause |
| ------ | ----------------------------------- | ---------------------------------------------- |
| `400` | `User already exists in the system` | Email exists and already belongs to a company |
| `400` | `User has already been invited` | A pending invite for this email already exists |
| `400` | `Failed to send invitation email` | SendGrid delivery failure |
***
## PUT /users//role
Update the role of a user within your company. Returns the updated user record.
**Request body:**
| Field | Type | Required | Description |
| ------------ | ------ | -------- | ----------------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `user_id` | string | Yes | ID of the user to update |
| `role` | string | Yes | New role: `admin`, `manager`, `standard`, `engineer`, `developer` |
```bash theme={null}
curl -X PUT "https://api.vh3connect.io/api:kP8T1CK7/users/42/role" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"user_id": "42",
"role": "manager"
}'
```
**Response:**
```json theme={null}
{
"id": 42,
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"username": "jsmith",
"role": "manager",
"profile_picture": { "url": null }
}
```
**Error responses:**
| Status | Error | Cause |
| ------ | --------------------------------------------------- | -------------------------------------------------- |
| `401` | `User not found or does not belong to this company` | `user_id` invalid or belongs to a different tenant |
***
## DELETE /users/
Archive (soft-delete) a user. The user's record is preserved but `is_archived` is set to `true`, they can no longer log in and will not appear in `GET /users/list`.
**Request body:**
| Field | Type | Required | Description |
| ------------ | ------ | -------- | ------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `user_id` | string | Yes | ID of the user to archive |
```bash theme={null}
curl -X DELETE "https://api.vh3connect.io/api:kP8T1CK7/users/43" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"user_id": "43"
}'
```
**Response:**
```json theme={null}
{
"success": true,
"user_id": "43"
}
```
**Error responses:**
| Status | Error | Cause |
| ------ | --------------------------------------------------- | -------------------------------------------------- |
| `401` | `User not found or does not belong to this company` | `user_id` invalid or belongs to a different tenant |
# Weather
Source: https://docs.vh3.ai/api-reference/weather
Forecast and historical weather for coordinates, jobs, and sites
# Weather
Weather lookups for field service planning and retrospective analysis. Backed by a third-party weather provider. Responses include hourly conditions and a summary with `outdoor_work_risk` (`low`, `moderate`, or `high`).
## GET /weather/forecast
Forecast weather for a latitude/longitude.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | -------------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `latitude` | float | Yes | Latitude (-90 to 90) |
| `longitude` | float | Yes | Longitude (-180 to 180) |
| `start_hour` | string | No | Window start (ISO 8601 partial, e.g. `2026-03-06T08:00`) |
| `end_hour` | string | No | Window end (ISO 8601 partial, e.g. `2026-03-06T18:00`) |
| `timezone` | string | No | IANA timezone (default `Europe/London`) |
**Response includes:** `mode` (`forecast`), `period_start`, `period_end`, `summary` (avg/min/max temp, precipitation, wind, `dominant_condition`, `outdoor_work_risk`), and `hourly[]` (temperature, humidity, precipitation, rain, weather code/label, wind, cloud cover).
**Enum, `summary.outdoor_work_risk`:** `low`, `moderate`, `high`
**Example:**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/weather/forecast" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "latitude=51.5074" \
--data-urlencode "longitude=-0.1278" \
--data-urlencode "start_hour=2026-03-06T08:00" \
--data-urlencode "end_hour=2026-03-06T18:00"
```
**Use cases:**
* **Dispatch planning:** Check conditions for a postcode centroid before assigning outdoor work.
* **Briefing enrichment:** Pair with `POST /briefing/generate` to surface visit-day risk in engineer packs.
***
## GET /weather/historical
Historical weather for a latitude/longitude and date range.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | --------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `latitude` | float | Yes | Latitude (-90 to 90) |
| `longitude` | float | Yes | Longitude (-180 to 180) |
| `start_date` | string | Yes | Start date (`YYYY-MM-DD`) |
| `end_date` | string | Yes | End date (`YYYY-MM-DD`) |
| `timezone` | string | No | IANA timezone (default `Europe/London`) |
**Response:** Same shape as forecast; `mode` is `historical`. Archive data is available from 1940 onwards.
**Example:**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/weather/historical" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "latitude=51.5074" \
--data-urlencode "longitude=-0.1278" \
--data-urlencode "start_date=2026-02-10" \
--data-urlencode "end_date=2026-02-12"
```
**Use cases:**
* **Delay analysis:** Correlate completed jobs with heavy rain or high wind on the service date.
* **SLA disputes:** Provide objective weather evidence for missed appointments.
***
## GET /weather/for-job/
Weather for a specific job. Coordinates and time window are resolved from the intelligence layer.
**Path parameters:**
| Param | Type | Required | Description |
| -------- | ------ | -------- | ------------------- |
| `job_id` | string | Yes | Job ID or reference |
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
**Behaviour:**
* Completed jobs (actual end in the past) → historical weather for the job window.
* Future or in-progress jobs → forecast for planned/actual start–end.
* Response includes a `job` object: `job_id`, `reference`, `site_address`, `status`.
**Example:**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/weather/for-job/FAB310221" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key"
```
**Use cases:**
* **Connie / agent tools:** Answer “was weather a factor on job X?” without manual coordinate lookup.
* **Investigation:** Combine with outcome search when diagnosing repeat failures or delays.
**Errors:** `404` if the job or linked site is missing; `422` if the site has no latitude/longitude.
***
## GET /weather/for-site
Weather for a customer or site over a date range. Coordinates are resolved from the graph.
**Query parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------------------------------------- |
| `company_id` | string | Yes | Your tenant identifier |
| `api_key` | string | Yes | Your tenant API key |
| `start_date` | string | Yes | Start date (`YYYY-MM-DD`) |
| `end_date` | string | Yes | End date (`YYYY-MM-DD`) |
| `contact_id` | string | No | Customer contact ID (preferred) |
| `site_key` | string | No | Site key (SHA-256); use when `contact_id` is unknown |
One of `contact_id` or `site_key` is required. When `contact_id` has no coordinates, the API falls back to the most recent linked site with lat/lon.
**Response includes:** Standard weather payload plus `site` (`contact_id`, `site_key`, `site_address`).
**Example:**
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/weather/for-site" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "contact_id=12345" \
--data-urlencode "start_date=2026-03-10" \
--data-urlencode "end_date=2026-03-12"
```
**Use cases:**
* **Account planning:** Review forecast for a key customer across a multi-day PPM window.
* **Site risk:** Assess outdoor-work risk at a repeat-failure location before scheduling.
**Notes:**
* `outdoor_work_risk` uses rule-based thresholds (heavy rain, gusts >60 km/h, freezing, snow/ice codes).
* Forecast horizon is up to 16 days; historical archive from 1940.
* Weather service errors return `502`.
# Authentication
Source: https://docs.vh3.ai/authentication
Two API surfaces, VH3 AI Intelligence (company_id + api_key) and BigChange API (X-API-Key header), plus per-user JWT for interactive apps
# Authentication
**Two server-to-server APIs, one key:** the same VH3 API key is used for both surfaces; transport differs.
1. **VH3 AI Intelligence** (`api:kP8T1CK7`): `company_id` + `api_key` on every request (POST body / GET query).
2. **BigChange API** (`api:YdihQNr3`): `X-API-Key` header only, no `company_id`; tenant resolved from the key.
**Interactive apps:** User Auth JWT (`Authorization: Bearer`) on `api:lBQnyyZL` and Bearer-enabled intelligence routes. Never send `api_key` from browser or mobile clients.
**Docs vs live data:** `https://docs.vh3.ai/mcp` or `https://docs.vh3.ai/llms.txt` for documentation search, not the VH3 product MCP.
VH3 Connect exposes **two REST API groups** for server-to-server integration, plus a **User Auth** API for interactive applications. You receive a single API key during onboarding; how you send it depends on which API you call.
## Two API surfaces
| API | Base URL | Auth | Tenant scope |
| -------------------------------------------------- | ---------------------------------------- | ---------------------------------------- | -------------------------------------- |
| [VH3 AI Intelligence](/api-reference/overview) | `https://api.vh3connect.io/api:kP8T1CK7` | `company_id` + `api_key` (body or query) | Explicit `company_id` on every request |
| [BigChange API](/api-reference/bigchange/overview) | `https://api.vh3connect.io/api:YdihQNr3` | `X-API-Key` header only | Resolved from the API key |
The API key is the same credential for both groups. Intelligence endpoints require your company ID in addition; BigChange proxy endpoints do not.
### VH3 AI Intelligence, quick reference
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/outcomes" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "boiler fault",
"limit": 5
}'
```
### BigChange API, quick reference
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 20
}'
```
### User Auth (interactive apps)
Login with email and password on `api:lBQnyyZL`; use the returned JWT as `Authorization: Bearer`. No API key in client code. See [User Authentication](#user-authentication) below.
***
## VH3 AI Intelligence authentication
All intelligence-layer endpoints require **company ID** and **API key** on every request.
| Field | Type | Description |
| ------------ | ------ | ---------------------------------------------------- |
| `company_id` | string | Your tenant identifier, identifies your organisation |
| `api_key` | string | Your tenant API key, authenticates the request |
These are passed on every request. For `POST` endpoints, they go in the JSON body. For `GET` endpoints, they go as query parameters.
Required on every VH3 data endpoint unless using Bearer JWT on User Auth–scoped routes. Missing either field returns HTTP 400 with `Missing param`.
### POST example (most endpoints)
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/outcomes" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "boiler intermittent fault",
"limit": 5
}'
```
### GET example (feeds, detail lookups)
```bash theme={null}
curl -G "https://api.vh3connect.io/api:kP8T1CK7/jobs/feed" \
--data-urlencode "company_id=your-company-id" \
--data-urlencode "api_key=your-api-key" \
--data-urlencode "page_size=20"
```
Requests missing `company_id` or `api_key` will receive a `400` response with a `Missing param` error.
***
## BigChange API authentication
BigChange proxy endpoints use the **same API key** as the intelligence layer, passed only in the **`X-API-Key`** HTTP header. Do not send `company_id` on these requests, the gateway resolves your tenant and BigChange session from the key.
```bash theme={null}
curl -G "https://api.vh3connect.io/api:YdihQNr3/contacts/contact" \
-H "X-API-Key: your-api-key" \
--data-urlencode "contactId=12345"
```
| Header | Required | Description |
| -------------- | ---------- | ------------------- |
| `X-API-Key` | Yes | Your tenant API key |
| `Content-Type` | Yes (POST) | `application/json` |
Missing or invalid `X-API-Key` returns `401 Unauthorised`. Do not put the API key in the JSON body for BigChange endpoints.
Full endpoint list: [BigChange API reference](/api-reference/bigchange/overview).
***
## User Authentication
For interactive applications, custom dashboards, customer portals, embedded tools, VH3 provides per-user authentication with JWT tokens. Users log in with email and password only. The tenant is resolved server-side from their account. After login, every call from the client uses the JWT, no API key is ever involved in client-side code.
### How it works
```mermaid theme={null}
sequenceDiagram
participant App as Your Application
participant Auth as User Auth API
participant API as VH3 Data API
App->>Auth: POST /auth/login (email, password)
Auth-->>App: { authToken: "eyJ..." }
Note over App: Tenant resolved server-side, JWT used for everything
App->>Auth: GET /auth/me (Authorization: Bearer token)
Auth-->>App: { id, first_name, last_name, email, role, ... }
App->>API: POST /connie/chat (Authorization: Bearer token)
API-->>App: { response data }
```
### Login
Authenticate a user with email and password. The user's tenant is resolved server-side, no API key is required from the client.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:lBQnyyZL/auth/login" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword"
}'
```
**Response:**
```json theme={null}
{
"authToken": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0..."
}
```
Store the `authToken` in your application (e.g. `httpOnly` cookie in production). All subsequent requests use `Authorization: Bearer `, no API key is ever sent from the client.
### Token refresh
Refresh an expiring token before it expires. Requires a valid Bearer token.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:lBQnyyZL/auth/refresh" \
-H "Authorization: Bearer eyJhbGciOi..."
```
**Response:**
```json theme={null}
{
"authToken": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0..."
}
```
### Get current user
Retrieve the profile of the authenticated user.
```bash theme={null}
curl "https://api.vh3connect.io/api:lBQnyyZL/auth/me" \
-H "Authorization: Bearer eyJhbGciOi..."
```
**Response:**
```json theme={null}
{
"id": 42,
"first_name": "Jane",
"last_name": "Smith",
"company_id": "abc-123-def",
"email": "jane@example.com",
"role": "admin",
"phone": null,
"profile_picture": { "url": null },
"_company": {
"id": "abc-123-def",
"name": "Acme Field Services"
}
}
```
### Token shape
JWT tokens issued by the User Auth API:
| Claim | Description |
| --------- | ------------------------------------------------- |
| `id` | User ID (integer) |
| `company` | Company ID (UUID), the tenant the user belongs to |
| `iss` | Token issuer |
| `exp` | Expiry timestamp (24 hours from issue) |
The same token works across both the User Auth endpoints and the main VH3 data API when configured with Bearer auth middleware.
### Using the token in your application
The example below stores the token in `localStorage` and calls the VH3 API directly from the browser. **This is for local development and testing only.** In any app that real users can access — including internal tools, partner portals, and MVPs — the token must be stored in an `httpOnly` secure cookie and all VH3 API calls must originate from your backend server. Calling the VH3 API from browser code means anyone who can open the browser network tab can replay those calls directly against your organisation's data.
```typescript theme={null}
// Development only — do not use this pattern in any user-facing application
const token = localStorage.getItem('vh3_token');
const response = await fetch('https://api.vh3connect.io/api:kP8T1CK7/connie/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify({
message: 'How many jobs were completed this week?',
}),
});
```
**In production:** store the `authToken` from `/auth/login` in an `httpOnly` secure cookie on your backend. On every request, your server reads the cookie, calls `GET /auth/me` to validate the token and retrieve the user's company, then makes the VH3 API call server-side. The browser never sees the token directly and never calls the VH3 API. See [Deploying secure apps](/guides/deploying-secure-apps) for the full frontend/backend pattern.
***
## User Management
VH3 provides two ways to manage users depending on your integration type:
| Use case | Endpoint set | Auth |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| **Back-end / server-to-server:** cron jobs, admin scripts, integrations | [`GET /users/list`, `POST /users/invite`, `PUT /users/{id}/role`, `DELETE /users/{id}`](/api-reference/users) on `api:kP8T1CK7` | `company_id` + `api_key` (server-side only, never sent from a browser) |
| **Interactive front-end:** custom dashboards, portals, embedded tools | [`POST /users/invite`, `GET /users/list`, `DELETE /users/{id}`](/api-reference/user-auth) on `api:lBQnyyZL` | Bearer JWT, no API key in client code |
Never call the `api:kP8T1CK7` user management endpoints from a browser or mobile app, doing so exposes your API key in client-side code. Use the JWT-authenticated equivalents on `api:lBQnyyZL` instead.
The section below covers the JWT-based variants for interactive applications. For the server-side `company_id` + `api_key` variants, see the [Users API reference](/api-reference/users).
Admin users can manage team members via the User Auth API. All user management endpoints require a valid Bearer token from a user with the `admin` or `developer` role.
### Invite a user
Send an invitation to a new user. Returns an invitation token (valid for 7 days).
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:lBQnyyZL/users/invite" \
-H "Authorization: Bearer eyJhbGciOi..." \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"role": "standard",
"first_name": "John",
"last_name": "Doe"
}'
```
**Response:**
```json theme={null}
{
"email": "newuser@example.com",
"role": "standard",
"invite_token": "eyJhbGciOi...",
"expires_in": 604800
}
```
| Parameter | Type | Required | Description |
| ------------ | ------ | -------- | ---------------------------------------------------------------------------------- |
| `email` | email | Yes | Email address to invite |
| `role` | string | No | Role to assign: `admin`, `manager`, `standard`, `engineer`. Defaults to `standard` |
| `first_name` | string | No | First name of the invited user |
| `last_name` | string | No | Last name of the invited user |
### List users
List all active users in the authenticated user's company.
```bash theme={null}
curl "https://api.vh3connect.io/api:lBQnyyZL/users/list?page=1&per_page=25" \
-H "Authorization: Bearer eyJhbGciOi..."
```
**Response:**
```json theme={null}
{
"items": [
{
"id": 42,
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"role": "admin",
"phone": null,
"profile_picture": { "url": null },
"email_verified": true
}
],
"curPage": 1,
"nextPage": null,
"prevPage": null
}
```
### Delete a user
Soft-delete a user (sets `is_archived` to true). Cannot delete your own account.
```bash theme={null}
curl -X DELETE "https://api.vh3connect.io/api:lBQnyyZL/users/42" \
-H "Authorization: Bearer eyJhbGciOi..."
```
**Response:**
```json theme={null}
{
"success": true,
"user_id": 42
}
```
### Roles
| Role | Permissions |
| ----------- | ----------------------------------------------- |
| `admin` | Full access, can invite, list, and delete users |
| `developer` | Same as admin |
| `manager` | Standard data access, no user management |
| `standard` | Standard data access, no user management |
| `engineer` | Standard data access, no user management |
***
## Your credentials
During onboarding you receive:
* **Company ID:** your unique tenant identifier
* **API Key:** your tenant authentication key
Both are provided by your account manager or visible in your VH3 Connect dashboard settings.
## Error responses
All errors follow a consistent format:
```json theme={null}
{
"code": "ERROR_CODE_INPUT_ERROR",
"message": "Missing param: company_id",
"payload": {
"param": "company_id"
}
}
```
| Status code | Meaning |
| ----------- | ------------------------------------------------------------- |
| `400` | Bad request, missing or invalid parameters |
| `401` | Unauthorised, invalid API key or expired token |
| `403` | Forbidden, insufficient role permissions |
| `404` | Not found, resource does not exist for your tenant |
| `409` | Conflict, a task is already running for this resource |
| `422` | Validation error, request understood but semantically invalid |
| `429` | Rate limited, too many requests |
| `500` | Server error, contact support |
## Security
* HTTPS only. Rotate API keys via account manager; do not log or echo keys in tool output.
* Intelligence: `company_id` + `api_key`. BigChange: `X-API-Key` header only (same key value).
* JWT `exp` is 24h; refresh before expiry. Claims: `id` (user), `company` (tenant UUID).
* Server-side user management: `api:kP8T1CK7` + `company_id`/`api_key`. Client-side user management: `api:lBQnyyZL` + Bearer only.
Your API key is tenant-scoped and grants access to your organisation's data only. Treat it like a password, store it in server-side environment variables only. **Never include it in client-side code, browser bundles, or mobile apps.** For interactive front-ends, use [User Authentication (JWT)](/api-reference/user-auth), users log in with email and password only, and the API key is never involved.
* All requests must use HTTPS
* API keys can be rotated on request via your account manager
* JWT tokens expire after 24 hours, use the refresh endpoint to obtain a new token before expiry
* Store JWT tokens in `httpOnly` secure cookies in production. `localStorage` is acceptable for local development only — never in user-facing apps
# Changelog
Source: https://docs.vh3.ai/changelog/overview
New features, updates, and fixes shipped in VH3 AI
No product changes shipped this week. The intelligence layer, [Connie](/guides/connie), [sentinels](/guides/sentinels), [reports and briefings](/guides/reports), [email triage](/faq/email-triage), and the [BigChange integration](/api-reference/bigchange/overview) continue to run as documented — see the [API overview](/api-reference/overview) for the current surface.
No product changes shipped this week. The intelligence layer, [Connie](/guides/connie), [sentinels](/guides/sentinels), [reports and briefings](/guides/reports), [email triage](/faq/email-triage), and the [BigChange integration](/api-reference/bigchange/overview) continue to run as documented — see the [API overview](/api-reference/overview) for the current surface.
## New features
**Intelligence layer launch.** The VH3 AI intelligence layer is live: a maintained operational graph, meaning-based search, structured job enrichment, and continuous monitoring across your field service data. See [Intelligence layer](/intelligence-layer) and [Introduction](/introduction).
**Connie.** Ask plain-language questions against your live operational graph and get cited, synthesised answers. See the [Connie guide](/guides/connie) and [Connie API](/api-reference/connie).
**Sentinels, cases, and teams.** Sentinels watch the graph 24/7 for repeat visits, SLA drift, dormant customers, and emerging risk — and can open a [case](/api-reference/cases), draft context with Connie, and route it to the responsible [team](/api-reference/teams). Read the [Sentinels guide](/guides/sentinels) and [Users and teams](/guides/users-and-teams).
**Email triage.** Inbound emails are classified, linked to the right job or account, and queued for the right team. See [Triage API](/api-reference/triage) and [Email triage FAQ](/faq/email-triage).
**Reports and briefings.** Scheduled and on-demand operational reports and briefings draw from the live graph. See [Reports](/api-reference/reports), [Briefings](/api-reference/briefings), and the [Reports guide](/guides/reports).
**Weather context.** Weather data is now available as first-class operational context for jobs and sites. See [Weather API](/api-reference/weather).
**Agent Starter Kits.** Ready-to-use configurations for connecting AI tools to the intelligence layer, including [AGENTS.md](/agent-kits/agents-md), [Cursor rules](/agent-kits/cursor-rules), the [VH3 product MCP](/agent-kits/mcp-setup), [Claude Projects](/agent-kits/claude-projects), [Claude Skills](/agent-kits/claude-skills), and [n8n agents](/agent-kits/n8n-agents).
**Verified n8n community node.** The official `n8n-nodes-vh3ai` node is [verified on n8n](https://link.vh3.ai/n8n), works on Cloud and self-hosted, and is usable as a tool by n8n AI agents. See [n8n community node](/n8n-node) and the [node reference](/agent-kits/n8n-node-reference).
**BigChange native integration.** Direct BigChange API coverage through the intelligence layer and the n8n node: contacts, jobs, invoices, quotes, sales opportunities, purchase orders, notes, persons, resources, vehicles, stock, worksheets, and reference data. See the [BigChange API overview](/api-reference/bigchange/overview).
## Updates
**Unified API surface.** A single OpenAPI specification now covers jobs, contacts, search, sentinels, reports, briefings, weather, triage, ingest, Connie, cases, teams, users, and user auth. Start at the [API overview](/api-reference/overview).
**Authentication and user auth.** End-to-end docs for tenant API keys plus end-user authentication flows. See [Authentication](/authentication) and [User auth API](/api-reference/user-auth).
**Ingest pipeline.** Continuous ingest with entity resolution keeps the operational picture current as customer hierarchies, sites, and job types change. See [Ingest API](/api-reference/ingest) and [Keeping the graph current](/guides/keeping-the-graph-current).
**Technology partners program.** Partner program details for FMS vendors, agencies, and platform integrators. See [Technology partners](/partners/technology-partners).
**Pricing published.** Transparent pricing for the intelligence layer, Connie, sentinels, and ingest. See [Pricing](/pricing) and the [pricing FAQ](/faq/pricing).
# Frequently asked questions
Source: https://docs.vh3.ai/faq
Common questions about VH3 AI — from what it is and how to get started through security, pricing, and building on the intelligence layer.
# Frequently asked questions
# Architecture and APIs
Source: https://docs.vh3.ai/faq/architecture-and-apis
API surfaces, authentication, and where your data lives.
## Architecture and APIs
You receive a single VH3 API key during onboarding. It is used across both server-to-server surfaces:
| API | Base URL | Auth |
| ------------------- | ---------------------------------------- | -------------------------------------------- |
| VH3 AI Intelligence | `https://api.vh3connect.io/api:kP8T1CK7` | `company_id` + `api_key` in the request body |
| BigChange API | `https://api.vh3connect.io/api:YdihQNr3` | `X-API-Key` header only |
Intelligence endpoints require your company ID on every request. BigChange proxy endpoints resolve your tenant from the API key alone.
For interactive applications and custom portals, users authenticate with email and password. The returned JWT is used for all subsequent calls. No API key is ever involved in client-side code.
See [Authentication](/authentication) for the complete surface map and code examples.
The public API reference documents the customer-facing subset. Additional endpoints exist for platform engineering, pollers, and operational tooling. Those internal endpoints are outside the integration contract. For integrations, use the endpoints documented here or the OpenAPI export your CSM provides.
| Layer | What is stored |
| --------------------- | ---------------------------------------------------------------------------------------------------- |
| Knowledge graph | Jobs, engineers, customers, outcomes, relationships, and SLA analytics, traversable in any direction |
| Semantic search index | Intake descriptions and diagnostic outcomes, indexed by meaning for fault discovery |
| Platform data | Cases, teams, notifications, usage, and configuration |
| Your FMS | Your operational system of record for dispatch, scheduling, worksheets, and job execution |
# Case management and teams
Source: https://docs.vh3.ai/faq/case-management-and-teams
Cases, teams, and how they enable continuous follow-through.
## Case management and teams
Case management is the place where agent signals become owned work. A case can represent an escalation, investigation, project review, audit, complaint, or follow-up item. It holds participants, linked operational records, comments, status changes, and a full activity timeline.
Operational records stay in the intelligence layer. Cases reference jobs, customers, sites, engineers, and other evidence so the team can review and act without copying data into a separate system.
Case management runs inside VH3 AI. It tracks ownership, evidence, and follow-through around operational work. Any BigChange write-back or job creation flow is handled by the configured ingest or integration pipeline for your tenant.
Teams are dynamic groups for shared ownership. A team can represent a region, customer portfolio, service line, escalation room, onboarding sprint, or temporary working group.
Teams can link to customers, sites, jobs, job types, or other entities. Sentinels, reports, Connie, and automations can then route work to the group that owns the relevant account, site, or problem.
Teams are created around the work. Some are permanent, such as a regional operating patch or customer portfolio. Others are temporary, such as a major incident room or a discovery sprint review group. Use `purpose`, `description`, and `metadata` to describe the group in the language your operation uses.
# Connie and AI agents
Source: https://docs.vh3.ai/faq/connie-and-ai-agents
Who Connie is, what BYOK means, models, tools, and MCP.
## Connie and AI agents
Connie is VH3 AI's field service operations agent in VH3 Connect. She reads your full intelligence layer: knowledge graph, semantic search, reports, weather, and enriched operational records. She runs on Anthropic's model family, with intelligent routing across multiple models and prompt caching built in so the right model handles each type of work efficiently.
Connie handles multi-turn operational reviews, account prep, diagnostics, and follow-through that depends on context from earlier in the session.
VH3 AI runs on an open AI harness. For conversational AI, you connect your own Anthropic account key. Every token Connie spends goes directly to your Anthropic account at your contracted rate. VH3 adds no margin. You see exactly what each session cost on your AI provider dashboard.
With BYOK, model usage is visible on your provider account. You can switch models, adjust usage, and see the full economics. If you build your own agents or automations via the API or n8n, you can use the model, harness, or framework you choose.
Connie uses Anthropic's model family, routed across multiple models depending on the task, with prompt caching for efficiency. Company-level context is cached across all users in your organisation, so every session benefits from prior cache warming. Enrichment and extraction pipelines use best-in-class structured output models selected by VH3. Embeddings are generated server-side by the platform.
Customers developing on the API or via n8n can use any model and framework they choose.
By default, Connie answers and investigates. Job creation from email goes through the portal ingest pipeline with review queues where configured. Write-back behaviour is integration-specific. Confirm with your CSM for your tenant's setup.
Tools are structured API operations that the agent can call with validated parameters: search, aggregate, investigate, job lookup, reports, briefings, and more. They give Connie and your custom agents precise access to the intelligence layer.
Yes. VH3 AI exposes a read-only MCP surface for approved agent clients such as Claude Desktop, Cursor, and coding agents. See [MCP setup](/agent-kits/mcp-setup) for configuration, authentication, and available operations.
# Data, graph, and search
Source: https://docs.vh3.ai/faq/data-graph-and-search
What lives in the knowledge graph, how search works, and data export.
## Data, graph, and search
Jobs are the central node, connected to customers, engineers, job types, outcomes, worksheets, equipment, and operational history. The graph captures relationships that match field service reality: the same engineer across different customers and locations, the same equipment across different sites, and patterns that cross account boundaries.
That connected structure makes questions answerable when they involve more than one record, for example repeat failures across a customer estate or engineer performance on one job type.
Finding semantically similar past jobs, for example "boiler pressure fault on a commercial site," using intake descriptions and diagnostic outcomes. Results are often combined with keyword search for exact part numbers or fault codes, giving precision and meaning-based discovery in the same query.
Job enrichment runs as data lands from your FMS. Customer summaries and some aggregate views refresh on scheduled tasks. The intelligence layer stays current as new jobs, outcomes, and customer activity arrive.
Discuss export and portability with your account team. Your operational records remain in your FMS. VH3 holds enriched analytics and the operational graph. On cancellation, export arrangements are handled according to your commercial agreement and data processing terms.
# Email triage and FM portals
Source: https://docs.vh3.ai/faq/email-triage
Email pipelines, portal routing, triage categories, and safety overrides.
## Email triage and FM portals
Four related but distinct pipelines:
| Pipeline | Creates jobs? | Purpose |
| -------------------- | -------------------------- | ------------------------------------------------------------------------ |
| Portal ingest | Yes (or queued for review) | Structured FM portal emails — Verisae, Bellrock, Greene King, and others |
| General triage | Yes (via pipeline) | Non-portal email extraction and routing |
| Classification only | No | Route and classify without job creation |
| Batch classification | No | Up to 50 emails per batch |
Portal emails are routed by sender before classification. If the sender matches a known portal, the email goes directly to portal ingest, saving classification cost. Extraction then combines deterministic parsing with structured AI to resolve customers, sites, job details, and priority from the portal format.
The default taxonomy includes ten categories, such as Technical Support and Maintenance, Health Safety and Compliance, Finance and Billing, and Delivery and Logistics. Tenants can apply custom taxonomies, including industry-specific category sets.
System-level safety overrides apply across all tenants for certain classifications, such as health and safety signals. These overrides are part of the shared safety policy and stay enabled for every tenant.
Portal and triage extraction use structured pipelines that combine pattern matching with targeted AI. They are optimised for high-volume, schema-driven output across varied email formats. Connie uses a conversational AI layer for reasoning, multi-turn dialogue, and cited answers.
# Getting started and onboarding
Source: https://docs.vh3.ai/faq/getting-started
What you need to connect, how quickly you see value, and how sentinels are configured.
## Getting started and onboarding
A typical onboarding needs:
* A VH3 tenant (company ID) in VH3 Connect
* Your VH3 API key, issued during onboarding
* Initial historical job sync (CSV or API poller)
* Optional: email routing, team and case setup
Your Customer Success Manager will confirm the connection path, data volume, exclusions, and first use cases before sync starts.
| Capability | Typical timeline |
| ---------------------------------------- | -------------------------------------------------------------------------------------- |
| Data flowing into the intelligence layer | Hours after sync starts |
| Search and basic analytics | As soon as jobs are ingested |
| Sentinels | Immediately — sentinels run against your full synced history from day one |
| Full enrichment backfill | Depends on volume; large tenants may take up to 12 hours for tens of thousands of jobs |
During onboarding, VH3 pre-configures your sentinels and syncs your full job history, so sentinels start detecting patterns against real data immediately. Noisy signals common to most field service operations are excluded from the start. You can refine thresholds and exclusions further with your CSM.
Yes. Sentinel exclusions filter specific engineers, job types, customers, and locations from individual sentinels. Contact your CSM to configure exclusions for your tenant.
BigChange is live in production with full ingestion, polling, enrichment, and entity resolution. Joblogic, Simpro, and others are on the integration roadmap. Ask VH3 for current partner pilot status.
# Pricing
Source: https://docs.vh3.ai/faq/pricing
Tiers, visit-based pricing, and the difference between Core and Core+.
## Pricing
VH3 AI uses a five-tier model from API through Core, Core+, Connect, and Enterprise, plus optional White Glove service tiers. Pricing is based on visit volume: the number of jobs enriched per month on graduated tiers. There are no per-seat fees. Plans and pricing are on [vh3.ai](https://vh3.ai). For a tailored projection, contact [hello@vh3.ai](mailto:hello@vh3.ai).
**Core** includes the full intelligence layer: Connie, AI agents, the operational graph, semantic search, sentinels, and reports.
**Core+** adds the native integrations layer: preconfigured connectors to third-party systems, user-based permissions mapping, and advanced workflow automation. It is the tier for operations that want structured data flows between VH3 AI and their wider tool stack.
# Reports, notifications, and operations
Source: https://docs.vh3.ai/faq/reports-and-notifications
Available report types and how notifications are delivered.
## Reports, notifications, and operations
VH3 AI supports daily operations reports, weekly summaries, account monthly reports, executive health checks, engineer performance, site health, customer intelligence, and sentinel digests. Reports draw from the same intelligence layer as Connie, discovery, and sentinels.
Notifications can appear in VH3 Connect, email, and deep links into specific surfaces such as a sentinel board, report, case, or job briefing. Automations can also route notifications to Slack, Teams, WhatsApp, or connected systems through n8n.
# Security and API keys
Source: https://docs.vh3.ai/faq/security-and-api-keys
Credentials, AI usage, and PII handling.
## Security and API keys
Each company receives a company ID and a VH3 API key during onboarding. Admin users can generate and manage API keys from the VH3 Connect dashboard. The key is issued by VH3 and scopes access to your organisation.
For intelligence endpoints, pass the API key alongside your company ID in the request body. For BigChange proxy endpoints, send it in the `X-API-Key` header. For interactive apps, users log in with email and password and all client calls use a short-lived JWT — no API key in client-side code.
See [Authentication](/authentication) for exact request shapes and examples.
Sentinel detection uses structured analytics on the operational model, keeping AI cost near zero at the watch layer. When a sentinel triggers, the result can be enriched with an AI-generated narrative so downstream agents and automations have context. Connie and email enrichment use LLMs where configured.
Enrichment pipelines normalise and, where appropriate, strip PII from text destined for semantic search. Contact records in the platform may hold PII for operational matching and are accessed only through authenticated VH3 surfaces. For contractual detail on data residency and processing, ask for your data processing agreement.
# Sentinels
Source: https://docs.vh3.ai/faq/sentinels
How sentinels work, severity levels, and false positive handling.
## Sentinels
24/7 automated monitors on engineer performance, customer risk, SLA clusters, and commercial signals. They run immediately against your full job history from day one — no warm-up period, no waiting for data to accumulate. They alert when thresholds are breached, not on every minor fluctuation, keeping the noise low and the signal meaningful.
Sentinels prioritise attention. They give the ops manager a daily or weekly list of the patterns that merit human review, so the team can spend less time scanning jobs and more time deciding what to do.
Thresholds are calibrated during onboarding to minimise noise. You can tune sensitivity per sentinel and apply exclusions for training roles, contractors, or entities that are not relevant to a particular signal.
| Level | Meaning | Suggested action |
| -------- | ----------------------- | ---------------- |
| Critical | Significant risk | Same-day review |
| Warning | Negative trend | Within 48 hours |
| Info | Heads-up or opportunity | Weekly digest |
Severity levels are fully configurable per sentinel. The consistency of levels is what enables deterministic, programmatic actions downstream: automations route Critical alerts to Slack immediately, open a case, or notify an account manager, all based on severity alone. Sentinels also monitor their own threshold performance and suggest adjustments when a setting is generating too much noise or missing signals.
Yes. Customer-oriented alerts include the customer name and reference so you can look up the account in BigChange immediately.
# Troubleshooting and support
Source: https://docs.vh3.ai/faq/troubleshooting
Common issues with API keys, sentinels, and email routing, plus who to contact.
## Troubleshooting and support
1. Your company ID matches the VH3 tenant issued at onboarding
2. The API key is your VH3 API key, issued during onboarding
3. You are calling `https://api.vh3connect.io`
4. The key has not been rotated without updating your integration
Contact your CSM or [support@vh3.ai](mailto:support@vh3.ai) if none of the above resolves the issue.
Confirm that jobs have finished syncing. Sentinels start once data is in place. If your sync is complete and nothing is triggering, check whether exclusion filters or thresholds are removing too much of the signal. Your CSM can inspect the sentinel configuration for your tenant.
Classification alone routes and labels the email. Job creation requires the configured portal ingest or triage pipeline. If you are using n8n, check that the automation calls the ingest step after classification. Contact your CSM to verify the pipeline for your tenant.
Your Customer Success Manager for onboarding, keys, and sentinel tuning, or [support@vh3connect.io](mailto:support@vh3connect.io) for general support.
# VH3 Connect and developer tools
Source: https://docs.vh3.ai/faq/vh3-connect
VH3 Connect as a product and the generative interface component toolkit.
## VH3 Connect and developer tools
VH3 Connect is the managed application built on the VH3 AI intelligence layer. It is where operators use Connie, review reports, manage cases, configure parts of the platform, and work with the intelligence layer through a ready-made interface.
VH3 AI ships a toolkit of typed interface components for developers building on the intelligence layer: investigation cards, job detail views, SLA gauges, maps, report sections, and more. These components map directly to the structured JSON that Connie and other tools return, so a developer can move from API response to rendered interface quickly.
This is a development toolkit for custom applications, partner integrations, and embedded surfaces. It is separate from VH3 Connect as a product.
# What is VH3 AI?
Source: https://docs.vh3.ai/faq/what-is-vh3-ai
What VH3 AI is, how it differs from your FMS, and what is included.
## What is VH3 AI?
VH3 AI is the intelligence layer for a field service operation. It ingests job data from field service management systems, enriches each record with structured analysis, connects jobs to customers, engineers, sites, outcomes, and history, then makes that picture available through Connie, reports, sentinels, search, and API tools.
The platform is built around field service work: engineers, customers, outcomes, SLAs, first-visit fix, and repeat failures. Every record is mapped into a structured operational model that compounds with each new job.
Your FMS remains the system of record for scheduling, worksheets, and day-to-day job execution. VH3 AI reads and analyses that data, plus email and optional workflows, to surface patterns, risks, and opportunities, without replacing dispatch or job creation in BigChange.
| Product | Role |
| ------------------------------- | --------------------------------------------------------------------------------------------- |
| VH3 Connect | Customer-facing web app — Connie, reports, triage queue, dashboards, teams, and cases |
| Connie | Conversational agent with tools over your full operational data |
| Sentinels | Automated 24/7 monitors for engineer, site, customer, and commercial signals |
| Email triage and portal ingest | Classify and route email; structured FM portal emails into the job pipeline |
| Case management | Incidents, investigations, audits — with participants, linked records, and activity timelines |
| Generative interface components | Typed components rendered from agent tool responses, for fast custom development |
Synthetic Operations Capacity is the extra operating capacity created when AI prepares work and people make the decision. Sentinels watch for patterns, Connie explains what is happening, cases hold the evidence, and dynamic teams own the follow-through.
A practical example: a sentinel detects repeat visits at a customer site, a case opens with the linked jobs, Connie drafts the brief, and the coordinator arrives to reviewed work with evidence attached.
Detection runs at near-zero AI cost. Enrichment and synthesis use AI where reasoning and narrative add genuine value.
# The 2027 blueprint
Source: https://docs.vh3.ai/guides/2027-blueprint
How field service organisations can turn operational knowledge into tools, automations, and intelligence they own
# The 2027 blueprint
Field service organisations are entering a period where software capability matters as much as fleet size, engineer coverage, and account relationships.
The change is practical. A small team with the right foundation can now build reports, automations, internal tools, and AI-assisted workflows in days. Work that once required a development team, a data engineering function, and months of integration can increasingly be assembled around the systems and knowledge the business already has.
The competitive gap is starting to form around that capability. The strongest operators will be the ones that can turn their own operational knowledge into useful tools quickly: a customer risk report before the QBR, a briefing that follows a specific job type, an alert that catches a quiet account before it becomes a churn risk, a workflow that removes a recurring manual step from dispatch.
This guide explains what that capability looks like, who should own it, and how VH3 AI helps your team build on top of the intelligence already inside your operation.
## Why this matters now
Field service businesses have always adapted their tools around the work. Spreadsheets, exports, inbox rules, shared folders, whiteboards, WhatsApp groups, and local reporting habits all exist because every operation has details that generic products miss.
The difference in 2026 is that those local adaptations can become real software. AI coding assistants, workflow automation, connected APIs, and prepared operational data have made lightweight internal tools much easier to create and maintain.
Every contractor now needs a practical software capability inside the operating model. Teams that build it can answer questions faster, make account risks visible sooner, brief engineers with better context, and remove manual coordination from work that happens every week.
Customers are moving in the same direction. FM managers, housing associations, retail heads, and facilities directors increasingly expect evidence: structured reports, performance data, automated updates, and clear explanations of what happened across the work. They notice the difference between a contractor that can provide that picture and one that still has to assemble it manually.
The important shift is ownership. A vendor can provide a platform, integrations, templates, and support. The business still owns the operational knowledge: how job types map to commercial reality, which customer patterns matter, which exceptions are routine, and where the friction actually sits between dispatch, delivery, and billing.
The 2027-ready organisation treats that knowledge as a capability to develop.
## The new operating capability
The building blocks that were once reserved for large vendors are now available to smaller operators: strong AI models, workflow automation platforms, coding assistants, API-first software, and documentation that AI tools can read directly.
The remaining advantage is operational knowledge. Your team knows how engineers describe faults, which account signals usually precede a complaint, where a job type name hides multiple kinds of work, and which customer relationships need careful handling. That knowledge is the raw material for useful intelligence.
A modern field service operation needs four connected capabilities:
* **Prepared operational data.** Jobs, customers, sites, engineers, outcomes, and history connected into a model that can be searched, analysed, and used by agents.
* **Reusable workflows.** Repeated manual work turned into automations that route the right information to the right team at the right time.
* **Internal tools.** Lightweight dashboards, forms, briefings, and reports built around how your operation actually runs.
* **Agent-ready context.** Coding assistants and AI agents given enough platform knowledge to build on VH3 AI safely and correctly.
VH3 AI provides the foundation for the first capability and gives your team the surfaces to build the other three.
## The field intelligence lead
Most teams can begin with one operationally fluent person who learns the tools, connects the right data, and turns repeated manual work into reusable workflows.
This person might be a new hire. They might be an account manager who already thinks in reports, a field engineer who keeps spotting better ways to work, or an operations coordinator who has been building unofficial spreadsheets and automations for years. Their background matters less than their proximity to the work.
Their role is to bridge the operation and the tooling:
* Find recurring manual work that can be automated.
* Turn common questions into reports, dashboards, and briefings.
* Help managers express operational rules clearly enough for tools to act on them.
* Maintain the connection between how the business really works and what the software is doing.
* Keep learning as AI coding tools, automations, and platform APIs improve.
There is a learning curve at the start. The tools are new, and the mental model is different from buying a finished product. The value compounds once the first few workflows are running. Every automation, report, and internal tool reduces the load on the rest of the business and gives the next project a better starting point.
For many organisations, this becomes a new operating role: the field intelligence lead.
## The four-part toolkit
The path to an intelligent, automated field service operation starts with a small set of tools used together.
**VH3 AI.** The intelligence foundation. Your job history, customer relationships, engineer performance, fault patterns, reports, sentinels, and conversational AI all draw from the same prepared operational layer. Your team connects it, configures it, and builds from the output.
**Workflow automation.** n8n and similar platforms let your team connect VH3 AI to email, Slack, Teams, WhatsApp, Xero, CRM tools, spreadsheets, and other systems. The VH3 AI n8n node gives builders pre-built operations for jobs, contacts, resources, intelligence feeds, and reports.
**AI coding assistants.** Cursor, Claude Code, and similar tools make lightweight internal software much easier to produce. With the VH3 AI starter context in place, a builder can ask for a dashboard, a small internal app, a report generator, or a workflow helper that uses the platform correctly.
**Agent starter kits.** The MCP server, AGENTS.md file, Cursor rules, Claude Project instructions, and skills give AI tools the context they need to work with VH3 AI correctly. They reduce the setup work and help the assistant understand the APIs, domain model, and safe patterns before it starts building.
Together, these tools let one capable operator build useful software around the way your organisation already works.
## What VH3 AI provides from day one
VH3 AI gives your team a foundation that would otherwise take years to assemble.
From day one, the platform connects to your FMS, reads your job history, and understands what each record means: engineer notes, outcomes, customer context, and the links between jobs, sites, engineers, and equipment. Reports, sentinels, and Connie all read from the same prepared picture. Your team, automations, and agents build on that output through the API, documentation, and starter kits.
That preparation matters because field service work is harder than simple reporting. A repeat fault at the same site should be visible even when engineers describe it differently. Account risk should surface before the complaint arrives. Historical data should stay usable as job types, worksheets, and operating habits change over time.
VH3 AI handles that so your team can focus on operational questions:
* Which sites are creating repeat visits?
* Which accounts need attention before the next review?
* Which engineers need a better pre-visit briefing?
* Which manual updates can move automatically?
* Which report should exist for this contract, region, or job type?
The platform is the starting point. The advantage comes from what your team builds on top of it.
## Building capability, not just buying tools
Traditional procurement starts with a product search. The team finds vendors, compares feature lists, negotiates a contract, and then adapts the operation around the chosen product.
The capability model starts with the operation. The team asks what repeated work should disappear, what questions should be answerable, what risks should surface sooner, and what customers should receive automatically. Then it uses VH3 AI, automations, and agent-assisted building to create the missing pieces.
Software buying still matters. Mature systems of record, accounting platforms, CRM tools, and communication products remain part of the stack. The capability sits above and between them, joining those systems together around the work.
Useful first projects are usually small:
* A weekly account brief that follows the structure your contracts team already uses.
* A pre-visit message for a specific class of repeat fault.
* A sentinel that opens a case when a risk pattern crosses a threshold.
* A dashboard for Monday operations review.
* A workflow that sends the right evidence to the right team when a customer escalates.
The measure of success is practical: faster answers, earlier action, better evidence, and less manual coordination.
## What VH3 AI commits to
VH3 AI is built as a harness for field service intelligence. We add capabilities, expand the API surface, deepen integrations, and evolve the intelligence layer continuously.
The agent kits, MCP server, n8n node, SDK, documentation, and API are designed to make the platform accessible to your team and to the AI tools they use. When model capabilities improve, your organisation can use them against the same prepared operational context. When new integrations become available, they connect to the same foundation.
The automations and tools you build are yours. The intelligence layer feeds them and keeps the operational context current. If you change workflow tools, the foundation stays. If you add or change field systems, the layer reconnects. The knowledge your organisation builds remains part of your operating capability.
## Where to start
Start with a focused first step.
Connect your operation to the intelligence layer and run a discovery sprint on recent history. Use the output to see what your data already contains: repeat patterns, customer risks, fault categories, engineer signals, and the questions the operation can answer immediately.
Then appoint the person who will own the first set of improvements. Give them one workflow, one report, or one operational question to solve. Keep the scope small enough to ship quickly and useful enough that the team feels the change.
Within the first 30 days, aim for one working loop: intelligence produced from your data, routed to the right team, used in a real decision, and improved from feedback.
That is how the capability starts to compound.
Connect your operation and see what the intelligence layer produces on your own data.
Give any AI coding assistant immediate fluency in the VH3 AI platform.
The VH3 AI node, pre-built templates, and the automation path from intelligence to action.
APIs, coding agents, and custom surfaces built on the intelligence foundation.
How the intelligence layer prepares your operational data before any question is asked.
If your operation runs on BigChange, start here.
# Agent observability
Source: https://docs.vh3.ai/guides/agent-observability
Why evidenced tool use matters when AI agents run real operations, and how VH3 AI surfaces provenance
# Agent observability
Non-deterministic systems are now part of running a field service business: routing assistants, diagnostic copilots, account briefings, and workflow agents that decide which API to call. They are fallible, like people, though often faster and more consistent on repetitive analysis. The operational mistake is treating the **final message** as the record.
You need to see **where the data came from**, **which tools ran**, and **what they returned** before you act on a recommendation, forward a briefing to a client, or open a case.
VH3 AI's flagship agent: long-running context, tool harness, and cited answers.
## The trust model
| Approach | What the user sees | Risk |
| ------------------- | ------------------------------------------------- | ---------------------------------------------- |
| **Black-box chat** | A paragraph of confident prose | No audit trail; hallucinated numbers look real |
| **Dashboard only** | Charts without narrative | Context and "why" live in someone's head |
| **Evidenced agent** | Answer plus structured tool results and citations | Reviewable, replayable, UI-friendly |
VH3 AI is built for the third row. Connie (and the same patterns on the API) returns:
1. **Natural language** for the human (headline, tables, next steps).
2. **`toolsUsed`** so you know which capabilities were invoked.
3. **`toolCallOutputs`** with the structured payload from each tool in that turn.
4. **`usage`** so token cost is visible on your provider account (BYOK-friendly).
5. **Diagnostic blocks** (when applicable) explaining how opening context was assembled.
The assistant text is the **interpretation**. The tool outputs are the **evidence**.
## Why this matters in field service
Operational decisions have consequences: dispatch changes, client calls, SLA credits, engineer callbacks, compliance sign-off. An agent that says "completion rate is down 12%" without traceability is unusable in a dispute. An agent that shows the aggregation window, the metric definition, and the underlying job references is **operations-grade**.
The same applies to **investigations** and **customer summaries**: the value is not only the headline ("roofing jobs are stalling at quote stage") but the **jobs cited**, the **confidence** stated, and the ability to open those records in your own UI.
Example: before an account manager tells a client that SLA completion fell last month, they should be able to see the aggregation window, excluded job types, and the job references behind the percentage.
## What the API returns
On [`POST /connie/chat`](/api-reference/connie), a typical successful turn includes:
| Field | Purpose |
| ----------------- | ----------------------------------------------------------------------------------- |
| `response` | Markdown answer for the user |
| `sessionId` | Thread identifier for follow-ups |
| `toolsUsed` | Ordered list of tool names executed this turn |
| `toolCallOutputs` | Array of `{ toolName, toolUseId, output }` with full structured results |
| `usage` | `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheCreationTokens` |
| `route` | How the message was classified (e.g. simple vs full agent), when routing is enabled |
| `summaryContext` | How customer opening context was built (server-enriched vs client fallback) |
| `preseedContext` | How company operating rules were loaded |
Example shape (abbreviated):
```json theme={null}
{
"sessionId": "session-abc-123",
"response": "Last week you completed **218** jobs, up from **195** the prior week...",
"toolsUsed": ["jobs_aggregate"],
"toolCallOutputs": [
{
"toolName": "jobs_aggregate",
"toolUseId": "toolu_01...",
"output": {
"total": 218,
"compareTo": { "total": 195, "deltaPercent": 11.8 }
}
}
],
"usage": {
"inputTokens": 4200,
"outputTokens": 380,
"cacheReadTokens": 3100,
"cacheCreationTokens": 0
}
}
```
Your application can render `toolCallOutputs` as tables, trend cards, or job lists **without parsing the markdown**.
`toolCallOutputs` is additive. Existing integrations that only read `response` keep working. New UIs should treat structured outputs as the source of truth for numbers and lists.
## Evidence inside tool results
Different tools expose different levels of provenance:
### Aggregations and feeds
`jobs_aggregate`, `job_feed`, and related tools return **counts, groups, and rows** with labels suitable for display. Connie is instructed to prefer correct **time axes** for field work (actual start/end vs planned vs created) and to note partial periods when comparing weeks.
### Search and precedent
Search tools return **hits linked to operational records**, not disconnected chunks. Your UI can show reference, customer, site, and outcome snippets from `output` while Connie summarises in prose.
On the **Connie agent path only**, `search_outcomes` and `search_intake` hits are returned as a shortened result set optimised for chat. The REST `POST /search/outcomes` endpoint still returns the full search API response with all indexed fields for your own UI or downstream tools.
Compact field set on the Connie path:
| Field | Role |
| --------------------------------------------- | -------------------------------------------------- |
| `jobRef` | Job reference for citations and drill-down |
| `contactName` | Customer/site label as shown on the job |
| `contactId` | Chaining to `contact_snapshot`, `job_detail`, etc. |
| `summary` | Plain-language outcome/intake summary |
| `actualStartAt` / `actualEndAt` | Visit timing (outcomes) |
| `createdAt` | Creation time (intake, when present) |
| `subVertical`, `status`, `result`, `score` | Classification and relevance |
| `jobId`, `typeId`, `categoryId`, `resourceId` | IDs for follow-up tools |
Verbose blobs (`text`, `companyId`) and opaque keys (`siteKey`) are omitted on the agent path to keep chat turns compact.
### Investigation
Investigation-style tools return a **headline**, **confidence**, **recommendations**, and an **evidence** list with job references. That is the pattern for "why" questions: synthesis with explicit citations and reviewable evidence.
### Customer knowledge
Customer Summary tools return **sectioned knowledge** (overview, patterns, risk, and related themes). `summaryContext` on the chat response tells you whether the opening block was server-enriched with recent jobs or supplied by the client.
## Tool recall across a session
Substantive tool results in a session can be **persisted and recalled** so later turns can reuse earlier evidence. From an observability perspective, that means:
* Turn 1: investigation on a customer issue → evidence stored.
* Turn 3: "show me that table again" → recall or re-fetch with continuity.
You still inspect `toolsUsed` on each turn to see whether the agent re-ran a tool or answered from session context.
## Generative UI and operational dashboards
VH3 Connect and integrator apps can map `toolCallOutputs` to **typed UI components** (metrics, job lists, investigation panels, report sections). The contract is: **one tool invocation → one serialisable payload → one renderer**.
That pattern matters because:
* **Numbers in the UI** come from JSON, not from regex on markdown.
* **Drill-down** uses the same `output` the agent saw.
* **Accessibility and export** (PDF, email) can reuse structured data.
Your app can render structured outputs without exposing internal field names to end users. **Structured outputs are first-class** in the API contract.
See [Generative UI](/guides/generative-ui) for the reference React component library that renders these payloads into investigation cards, gauges, reports, and job detail views.
## Routing and cost transparency
When message classification is enabled, `route` describes how the message was classified before the full agent ran. Simple acknowledgements may skip the tool loop entirely; analytical questions use the full set of connected capabilities. That is observability for **cost and behaviour**, not only for correctness.
Combine `route` with `usage` to answer: "Was this an expensive turn? Did we need tools at all?"
## Practices for reviewers and builders
In internal tools, render `toolCallOutputs` beneath or beside the assistant message. Hide only in consumer-facing views where space is tight, with a "View source data" affordance.
API keys belong server-side. Log `sessionId`, `toolsUsed`, and redacted outputs in your own audit store if required for compliance.
Investigation and narrative reports take longer than discovery. Observability includes **latency**: if `toolsUsed` is empty and `response` is vague, check for timeout or guardrail routing.
For high-stakes checks, cross-call [`POST /search/outcomes`](/api-reference/search) or job feed endpoints with the same scope Connie used. Same substrate, deterministic replay.
## Humans and agents together
Agents will not replace accountability. They **compress time to insight** when the harness is sound: prepared data, correct tools, cited results, and transparent usage. Observability is how you keep them **accountable** as you deploy them into dispatch, account management, and leadership workflows.
Fallibility does not disappear. It becomes **visible**, which is the difference between a demo and production.
## Related
Capabilities, sessions, and efficient use of the layer.
Deterministic search and entity resolution for verification.
Prepared operational memory vs classic retrieval.
Full request and response fields.
# AI Act and engineer data
Source: https://docs.vh3.ai/guides/ai-act-and-engineer-data
How VH3 AI handles engineer-level performance data, what your obligations are as the deployer, and a notice template you can adapt
# AI Act and engineer data
This guide is for **operations leaders, DPOs, and works-council representatives** at field-service businesses using VH3 AI in the EU or UK. It explains how the platform handles data about your engineers, what we have built in to keep that handling defensible, and the parts that remain your responsibility under the EU AI Act and GDPR.
Drop-in Markdown you can adapt and publish on your intranet.
## 1. How responsibility splits
VH3 AI Ltd builds and supplies the platform. Your organisation operates it inside your service business and decides which users see what. Under the AI Act, that split has a name:
| Role | Who | What that means in practice |
| ---------------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Provider** of the foundation AI models | Anthropic, Google | Train and supply the underlying language models. Conformity obligations sit with them. |
| **Provider** of the operational platform | VH3 AI Ltd | We build the tools, system prompts, evaluation, and guardrails around those models for field service. |
| **Deployer** | Your organisation | You decide who can ask what, in what context, and how outputs feed into decisions. The transparency and human-oversight duties for your workforce sit with you. |
We design for the deployer obligations on your side — but we do not perform them on your behalf. The notice and oversight steps in section 4 are yours to operate.
## 2. Why engineer-level data is treated differently
Most of what VH3 AI processes is operational data about jobs, sites, customers, and equipment. A subset is about named field engineers: who attended a job, when it started and finished, what the outcome was. The AI Act treats AI systems that **monitor and evaluate the performance of workers** as high-risk (Annex III, Category 4).
That classification triggers obligations whether you call the system "monitoring" or not. Practical signals that matter:
* Reports that name individual engineers alongside completion rate, on-time percentage, or job volume.
* Sentinels that flag a specific engineer for review.
* Connie answers that compare named engineers or summarise a single engineer's recent work.
All three exist in the platform because they are useful for service-quality management. They also need to be handled with care.
## 3. What VH3 AI does at the platform level
These are the design choices we have made so that the high-risk surfaces stay defensible. None of them remove your deployer obligations, but they reduce the operational and legal risk of using the features.
Engineer dashboards and report sections present individual metrics (completion rate, on-time percentage, job count) separately. The platform does not synthesise a single "engineer quality" number.
Connie is instructed to answer operational questions about engineers and to decline questions framed as HR decision support — for example, "who should I put on a performance improvement plan?" or "rank these engineers for promotion."
The assistant is instructed not to infer emotional state, motivation, attitude, or mental health from job notes or operational data. Sentiment classification on inbound email is suppressed for internal employee-to-employee communications.
Engineer-category sentinel triggers and the engineer performance tool responses both carry an operational-metrics disclaimer. Connie surfaces this caveat when she presents the data.
You can exclude individuals (resident engineers, subcontractors, anyone you choose) from engineer sentinels. See [Sentinels](/guides/sentinels) for the exclusion model.
Sentinel triggers create [cases](/guides/users-and-teams) for review. They do not write back to HR systems or trigger employment actions automatically.
## 4. What sits with you as the deployer
Four things stay your responsibility, regardless of what we build at the platform level.
Under GDPR Articles 13 and 14, your engineers should be told that their operational performance data is processed by an AI system and what it is used for. The template in section 5 gives you a starting point.
AI outputs should not be the sole basis for any employment decision. Pair them with direct observation and conversation. Note this in your performance-review process.
Decide which engineers fall inside the scope of monitoring, and which (typically resident engineers and subcontractors) do not. Use the exclusion controls to reflect that decision. Decide which roles in your organisation can ask engineer-specific questions.
Connie session history and operational data retention should align with your wider employment-data retention policy. Speak to your CSM if you need help configuring this.
## 5. Sample engineer notice template
A Markdown notice you can adapt and publish to your intranet or staff handbook. Replace each `{{PLACEHOLDER}}` with your own value, review with your DPO, then issue before AI-derived performance data is used in a review or coaching conversation.
```markdown theme={null}
# How we use AI to support service-quality management
**Issued by:** {{COMPANY_NAME}}
**Date:** {{DATE}}
**Last reviewed by:** {{DPO_OR_HR_CONTACT}}
## What this is
{{COMPANY_NAME}} uses an AI-powered operational intelligence platform
(VH3 AI) to help us understand and improve how our field service
operation runs. This notice explains, in plain terms, what data about
you flows through the platform and how we use it.
## What data about you is processed
The platform reads operational data that already exists in our job
management system:
- Your name and engineer ID.
- The jobs you have been assigned and have completed.
- For each job: customer, site, planned and actual times, outcome
status, and free-text notes added to the job record.
- Aggregations derived from the above (your completion rate, on-time
rate, job volume over a given period).
The platform does **not** access your personal email, calendar, or any
communications outside the job system. It does not process biometric or
wellbeing data. It does not infer your emotional state or motivation
from job notes. It does not produce a single "engineer quality" score.
## Why we process this data
We rely on our legitimate interest in monitoring and improving the
service we provide to our customers, and in supporting our engineers
with timely coaching when patterns suggest it (GDPR Article 6(1)(f)).
{{ADJUST IF YOU RELY ON A DIFFERENT BASIS OR HAVE A WORKS-COUNCIL
AGREEMENT COVERING THIS PROCESSING.}}
## How the AI is used
- **Operational dashboards and reports.** Managers and coordinators
can see team-level and engineer-level metrics over time.
- **Sentinels.** Background checks flag patterns such as a run of jobs
completed with issues. A manager reviews any flag before raising it
with you.
- **Assistant (Connie).** Managers and coordinators can ask the
platform questions about the operation. It is instructed to present
operational metrics only and to decline questions framed as
employment recommendations.
## Decisions about your employment
AI-generated outputs are not the sole basis for any employment
decision. Decisions about your performance, role, training, or any
disciplinary matter remain decisions made by your manager (and, where
appropriate, HR) on the basis of a full picture, including direct
observation and your right to provide context.
You have the right not to be subject to a decision based solely on
automated processing (GDPR Article 22). We do not make such decisions
about you using this platform.
## Your rights
You have the right to:
- Access the operational data we hold about you (Article 15).
- Have inaccurate data corrected (Article 16).
- Object to processing based on legitimate interests (Article 21).
- Lodge a complaint with {{COUNTRY_DPA_NAME}}.
To exercise any of these rights, please contact {{DPO_OR_HR_CONTACT}}.
## Retention
We retain operational job data for {{RETENTION_PERIOD}}. AI assistant
conversation history is retained for {{ASSISTANT_RETENTION_PERIOD}}.
## Third parties
The platform is operated by VH3 AI Ltd as our processor under a data
processing agreement. It uses foundation AI models from
{{LIST_PROVIDERS_IN_USE}} to generate analytical responses. No data is
sold to third parties or used to train foundation models.
## Updates
If we materially change how we use the platform, we will issue an
updated version of this notice. You can find the current version at
{{INTERNAL_LINK}}.
{{SIGNATORY_NAME}}
{{SIGNATORY_ROLE}}
```
## 6. Checklist before you issue the notice
* [ ] DPO or legal counsel review complete.
* [ ] All placeholders replaced.
* [ ] Lawful basis appropriate for your jurisdiction and any applicable collective agreement.
* [ ] Retention periods aligned with your wider data retention policy.
* [ ] Internal page set up where engineers can re-read the notice at any time.
* [ ] Process in place to handle Article 15, 16, and 21 requests.
* [ ] Works-council or employee-representative consultation completed where required.
## Related
The monitoring layer and the exclusion controls.
Access, roles, and how cases route to the right people.
The assistant and the compliance boundaries built into it.
Wider governance and IT-checklist view.
# AI you can check
Source: https://docs.vh3.ai/guides/ai-you-can-check
Why traceability matters more than confidence in field service operations, and how VH3 AI builds evidence into every answer
# AI you can check
There is a version of AI in field service that sounds very useful.
Ask it how an account is performing. It produces a confident paragraph: volume is up, first-time fix is strong, no SLA concerns flagged.
The paragraph is well written. It sounds authoritative. Nobody in the room knows where the numbers came from.
That is the version to be cautious about.
## The gap between the number and the truth
Field service operations generate a lot of apparent certainty.
The FMS says first-time fix is 77%. That number is real. It is also incomplete.
Jobs marked `completedOk` include visits where the engineer resolved the presenting symptom but not the underlying fault. Within 30 days, the same site books again, for the same asset, with the same complaint. That visit appears in the records as a new job — not as evidence that the first visit did not actually fix anything.
Adjust for same-fault return visits within 30 days and the first-time fix rate at the same operation might be closer to 68%. Both numbers are "correct" by the definition used to calculate them. Only one is operationally useful.
The same pattern appears across most operational metrics.
A "Pricing Required" status looks like progress. It might be a quote black hole — work scoped, priced never submitted, or submitted and ignored, with no chase mechanism.
An overdue compliance job does not appear on any invoice. It does not show up on any dashboard unless someone specifically builds a query for it.
A completed job is not always a resolved fault. An engineer who clears a symptom, closes the job, and moves to the next call is doing their best with the time available — but the operational record will not separate "resolved" from "cleared for now."
None of this is a technology problem. It is a characteristic of operational data. Every field service business that runs a serious account review eventually learns to cross-reference, question the source, and build confidence through triangulation, not through a single number.
## Why AI does not automatically solve this
AI handles operational data the same way that data actually is: incomplete, inconsistently recorded, and optimised by the people who produced it for the immediate task at hand, not for downstream analysis.
A model that is given the raw job record will produce an answer consistent with that record. If the record says `completedOk`, the model has no reason to look for the follow-on visit two weeks later. If the engineer wrote "issue resolved, system operational," the model will reflect that.
The problem is not model intelligence. It is what was in the source data, and whether the system was designed to cross-reference it.
A clean paragraph of analysis, produced from an incomplete input, is a confident wrong answer.
The right question to ask of any AI working inside your operation is not "does this sound plausible?"
It is: "what records did this come from, and can I check them?"
## What checkable AI looks like in practice
Checkable AI does not mean slow AI. It means AI that carries its evidence.
**Citations in answers.** When Connie answers "which engineers had the most repeat visits last month?", the answer includes the job references behind the aggregation. The operations manager can open those jobs and verify the count, check the dates, and confirm the scope. The answer is not just a number. It is a number with a paper trail.
**Defined scope.** A report that says "first-time fix rate was 76% last month" should state the aggregation window, the job types included, and whether cancelled or aborted jobs were counted. Without that, the same metric will produce different numbers from different tools, and the operations team spends review meetings arguing about which number is right rather than what to do about it.
**Deterministic signals.** Sentinels in VH3 AI run as database checks, not model inference. When a sentinel flags that a customer has had three repeat visits in 60 days, that is a query result, not a model judgement. It can be reproduced. It can be audited. If the threshold is wrong, it can be adjusted. The signal has a definition behind it.
**Human review inside the workflow.** Investigations carry the jobs, evidence, and basis in the output — not just the conclusion. A case opened by a sentinel includes the linked job records, the timeline, and the flagging criterion. The account manager who owns the case can look at the evidence and decide whether it is worth acting on. The AI has done the work of surfacing and assembling; the human makes the call.
**Visible model usage.** With BYOK, the token spend on Connie and agent sessions is visible on the customer's own model provider account. The model used, the input and output token counts, and the cost are auditable, not bundled into a subscription line item. That gives you transparency about what the model was asked to do, as well as cost control.
## The operational case for traceability
An account manager who walks into a customer review with a report produced by an AI system has two choices.
They can present the headline numbers and hope the customer does not ask how they were calculated.
Or they can walk in with the report, the underlying job references, the evidence behind each finding, and the ability to answer "show me the jobs that drove that number" in real time.
The second version builds a different kind of relationship.
The same applies internally. An operations director who receives a sentinel alert about engineer performance has to decide whether to act on it. If the alert is a paragraph of analysis with no traceable source, acting on it affects a person based on something unverifiable. If the alert includes the jobs, the dates, the pattern definition, and the threshold, it is a basis for a conversation — not a verdict.
Operational AI that carries its evidence makes better conversations possible. It does not replace human judgment. It gives that judgment something solid to work from.
## How VH3 AI is built for this
The design principle throughout VH3 AI is that the interpretation is what the AI produces, and the evidence is what the AI carries.
Connie's answers include `toolsUsed` and `toolCallOutputs` — the structured results from every tool call in that turn, alongside the natural language response. The assistant text is the synthesis. The tool outputs are the record.
Investigation cards expose the jobs, sites, and engineers connected to each finding. SLA gauges show the aggregation window and the criteria. Report sections link to the operational records behind each metric.
Sentinels are defined and adjustable. The threshold, the scope, and the frequency are set by the operations team, and the firing criteria are visible to any team member who wants to understand why something was surfaced.
VH3 AI is built as operational software where every surface carries its evidence. Connie, investigations, sentinels, and reports all link back to job references, tool outputs, or defined criteria — because field service work has consequences. Dispatch decisions, compliance sign-off, engineer performance conversations, customer escalations, and SLA credits affect real people and real relationships. The AI that supports those decisions should make it easier to get them right, with evidence your team can verify before they act.
Tool calls, data sources, cost, and handoffs — what the API returns with every Connie turn.
How VH3 AI prepares operational context before any question is asked.
How deterministic monitoring works and how to set thresholds your team trusts.
How evidence becomes owned work with a defined next step.
# VH3 AI for BigChange users
Source: https://docs.vh3.ai/guides/bigchange
How VH3 AI reads your BigChange history, connects your operation, and puts answers in front of your team
# VH3 AI for BigChange users
If your operation runs on BigChange, VH3 AI starts with the data your team already depends on: completed jobs, engineer visits, worksheets, customer records, job types, notes, and the shorthand your coordinators use every day.
BigChange remains the system of record for dispatch, scheduling, job tracking, and worksheet capture. VH3 AI sits alongside it: reads your job history, connects every record to the right customer, site, and engineer, watches for patterns across thousands of jobs, and puts answers in front of your team before they go looking.
Connect BigChange once and your operational history starts feeding search, sentinels, reports, Connie, and the workflows your team uses to follow through.
## We know what your data looks like
We built VH3 AI on BigChange data from live field service operations before the product had a name. That matters because real operational data carries years of local decisions.
Over years of operation, the shape of your data changes. Custom fields configured at go-live drift in meaning. Worksheet structures get updated and historical answers stop mapping cleanly to how the operation runs today. Contact hierarchies evolve. Job types get renamed or consolidated. The same underlying fault gets described differently by different engineers at different points in time.
That is how field service operations actually run. VH3 AI has to understand the drift, resolve the entities, and keep historical records useful without changing the source system.
We have processed hundreds of thousands of BigChange jobs across live customer operations. The enrichment pipeline was built around operational reality: messy notes, renamed job types, changing worksheet structures, and long-running customer histories. When your jobs land, VH3 AI extracts the fault type, structures the work performed, identifies equipment context, and links engineers, sites, customers, and history into one connected picture.
## Operational data quality over time
Long-term intelligence needs a place to hold corrections, mappings, and operational interpretation above the raw API records.
Timing data is particularly unreliable in mature operations: jobs that stayed open because of admin backlogs, completion timestamps that reflect paperwork processing time, SLA calculations distorted by open records that were never formally closed. A job type called "Reactive Maintenance" in 2021 and "Emergency Callout" in 2023 may be the same work. An open job from eighteen months ago may have been completed but never updated.
BigChange correctly preserves what was recorded at the time. That immutability is valuable — and accurate long-term intelligence needs more on top of it.
VH3 AI holds those corrections above the source system: resolved entity mappings, corrected timing data, unified job categories across historical periods, and open-job handling that reflects operational reality over administrative backlog.
When those corrections live in a prepared operation, search, reports, sentinels, and Connie all read from the same reconciled picture — and the intelligence improves as your history grows.
## What building on BigChange data involves
Dispatch, scheduling, job tracking, and worksheet capture are one engineering problem. Turning that data into useful intelligence — patterns spotted, precedents findable, risks flagged, briefs ready — is another.
Any team that has attempted it directly knows the work involved. Data needs to be fetched, shaped, and normalised before it can be used analytically. Jobs need to be linked to engineers, sites, customers, and history. Similar faults need to be findable even when they were described differently. Patterns need to be watched continuously and routed to the people who own them. All of it has to stay coherent as the data grows and evolves.
VH3 AI packages that foundation so your team starts with a prepared operation, ready to search, watch, and brief from day one.
## The right first step into AI for your operation
Most organisations thinking about AI for field service are looking for a practical first step. They have heard pitches. They have seen demos. They are rightly cautious about committing to something that locks them into a vendor, requires a long implementation, or produces results six months from now that nobody is sure how to measure.
The practical starting point is your own BigChange history. You connect your BigChange account. We process your history, build customer and job profiles, and connect the dots across jobs, engineers, sites, customers, and outcomes. Within hours, you have a working operational picture: job patterns structured, customer knowledge generated, sentinels monitoring your operation, reports running on schedule, and Connie ready to answer questions in plain English against your actual data.
Sentinels watch continuously with near-zero AI cost at detection, so your team sees what changed without paying for a model call on every check.
Connie's answers come with citations. The source of every number is traceable. Trust builds from evidence: job references, customer names, structured outputs, and reports your team can check.
Start with one use case. The discovery sprint gives you a structured operational profile from recent history before you decide what to build next.
## What changes in day-to-day work
The value shows up in ordinary operating rhythms:
* The morning performance picture arrives before the standup.
* A drifting customer account is flagged while there is still time to act.
* Repeat visits and SLA clusters appear in sentinel digests during the month.
* Engineers arrive on site with a briefing that includes relevant history and similar faults.
* Account managers walk into reviews with a report built from the operational record.
The same intelligence is available through the API for teams that want custom dashboards, automations, or partner-facing surfaces. New reports and workflows build on the prepared operation.
If your stack changes later, your enriched history gives you a stable place to connect the next source system. If BigChange adds new useful fields, they can be ingested. If an acquisition brings another field system, VH3 AI can connect that history into the same picture.
## First week with your BigChange data
A simple first-week loop helps the team see the value quickly:
1. Run one discovery search for a fault your team remembers well and inspect the top three precedents.
2. Open Connie on a real customer question and check the job references she cites.
3. Review the first sentinel digest and pick one finding to action.
4. Read the weekly or account report and compare it with the story your team already knows.
5. Open a case for one follow-through item if your tier includes cases and teams.
See [Working with your operation](/guides/working-with-your-operation) for the broader operator playbook.
## Time to value
Onboarding starts with a discovery sprint. We take a sample of your recent BigChange history and run it through the enrichment pipeline. Within a few days, you have a structured operational profile of your business: top fault categories, repeat failure patterns by site, engineer performance signals, customer risk flags, and the questions your data can answer today.
The discovery sprint uses your data and produces an operational profile your team can inspect before a longer commitment.
From there, full historical ingestion brings in your complete job history, typically two to three years. Live polling keeps your operation current as new jobs complete in BigChange. Enrichment compounds over time. The patterns that were invisible in raw exports become visible in the connected picture.
Automation templates give your team useful workflows from day one: daily briefings, sentinel digest emails, Slack or Teams notifications when something crosses a threshold, report distribution, and more. They are running workflows that you extend when you are ready.
## What we support you with
Our team understands BigChange operations from the inside. We know how to map your job types, your worksheet structures, your customer hierarchies, and your custom field configuration so the output is useful from day one — mapped, enriched, and ready to query. That initial configuration work is part of what you get.
For automation and integrations, the pre-built n8n workflow templates give most operations a working foundation on day one. If your operation needs something different, we build it. We connect to the tools your team already uses: accounting, CRM, communication, scheduling. Those connections deepen the intelligence over time by bringing more operational context into the same picture.
For teams that want to go further, the platform is fully open through the API. Your developers can query the prepared operation, call Connie programmatically, trigger reports, build custom dashboards, and connect the intelligence to any surface your team works from. The starter kits for coding agents, Cursor, and Claude give your technical staff a running start.
We work closely with the operations we onboard so the platform becomes part of how the business runs — and your team can own it day to day.
## Related
The full BigChange data surface available through VH3 AI: jobs, contacts, finance, worksheets, and more.
How VH3 prepares your operational data before any question is asked.
Watches your BigChange operation around the clock and surfaces patterns before they escalate.
How to get the most from Connie, discovery, and sentinels day to day.
The free n8n node and pre-built workflow templates for BigChange operations.
For technical staff and developers: APIs, agents, and custom surfaces.
# Building on the layer
Source: https://docs.vh3.ai/guides/building-on-the-layer
Citizen builders, coding agents, and integrations on a secure operational substrate
# Building on the layer
An operations manager routes a sentinel digest to Slack. A coordinator builds a workflow for engineer follow-ups. A developer opens Cursor and asks it to build an account review panel against the VH3 AI API. Each builder is working on the same prepared operational model.
VH3 AI is designed as a secure operational substrate:
* Jobs and relationships are enriched once and stored in infrastructure scoped to your organisation.
* Fast discovery (search, similarity, entity resolution, customer knowledge sections) reads that model without an LLM.
* Agents, reports, and automations read the same model when they need language and narrative.
* Connected tools (email, calendar, CRM, storage, field systems) feed **entities back** into the same graph through managed sync and resolution.
This guide is for **builders**: operations staff using no-code tools, and technical staff using Claude Code, Cursor, or similar coding agents.
**Are you an operator or an IT lead?** Operators should start at [Working with your operation](/guides/working-with-your-operation); IT leads deploying internal apps should read [Deploying secure apps](/guides/deploying-secure-apps) for governance and auth patterns. This page focuses on builder workflows.
How search, customer knowledge sections, and entity resolution work on the layer.
## What integrating AI should mean in field service
| Maturity | What the business has |
| -------------------- | ------------------------------------------------------------- |
| **Level 1: Access** | Exports and dashboards; questions wait for manual analysis |
| **Level 2: Ask** | Chat over files; answers are not durable or shared |
| **Level 3: Model** | Persistent graph, enriched jobs, fast discovery, sentinels |
| **Level 4: Operate** | Agents, automations, cases, custom apps on the same substrate |
VH3 AI targets levels 3 and 4. Level 2 is where cost and trust break down: every session re-interprets raw text, and nothing belongs to the organisation in a structured form.
**Data sovereignty** means your enriched operational intelligence is tenant-isolated, portable, and usable outside a single vendor UI. You can connect your own models (BYOK), your own automations, and your own applications. The platform fee covers the intelligence layer; agent token spend stays visible on your provider account.
## Three builder paths (same foundation)
n8n, templates, Connie in Claude Projects. Solve local problems without a development queue.
Cursor, Claude Code, MCP. Generate apps and integrations against a documented API.
Direct API integration, custom UIs, partner solutions. Full control, full responsibility.
All three paths call the **same APIs** and read the **same operational model**. Each builder works from the same resolved customers, jobs, sites, and engineers.
One reason that holds: VH3 AI maintains a canonical domain model for field service. Every record that enters the platform, regardless of source system, is resolved into that model before it touches the graph. A job is a job. A customer is a customer. The model's schema is not exposed, but the contract it delivers is: consistent, resolved, connected entities at every endpoint. When you build an app or an automation on this layer, you inherit that consistency. See [The domain model](/intelligence-layer#the-domain-model-why-the-substrate-speaks-one-language) in the intelligence layer guide.
## The tool surface (at a glance)
The substrate is only half the story. The other half is the tool surface that sits on top, the same tools Connie uses internally, also available to your agents, automations, and apps.
| Class | Tools | What they do |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| **Discovery** (no LLM) | `/search/outcomes`, `/search/intake`, `/search/autocomplete`, `/search/summary-sections`, `/jobs/feed`, `/jobs/aggregate`, `/contacts/feed`, `/dashboard/snapshot`, `/weather/*` | Sub-second lookups: precedents, entity resolution, account hierarchies, KPIs |
| **Monitoring** (no LLM at detection) | `/sentinels/run`, `/sentinels/digest`, `/sentinels/results` | 24/7 pattern detection on the graph |
| **Synthesis, conversational** (BYOK) | `/connie/chat`, `/investigate` | Cited narrative, multi-step diagnosis |
| **Synthesis, platform** (included) | `/briefings/*`, `/reports/generate` | Pre-visit briefings, scheduled report generation |
| **Workflow** | `/cases/*`, `/teams/*`, `/users/*`, `/auth/*` | Cases, teams, users, JWT sessions for ownership and access |
| **Ingest** | `/triage/classify`, `/ingest/email-portal`, native integrations | Inbound triage and structured extraction |
This is the surface a coding agent or n8n workflow calls. Sentinels are how the platform notices things; discovery and synthesis are how it answers; cases and teams are how it follows through. The full inventory, with patterns and evaluation notes for AI agents reading the docs, is on [Platform tools](/guides/platform-tools).
Every tool, what it does, when to reach for it, and the patterns that get the most out of them. Use this page if you are evaluating VH3 AI for a build.
## Connected tools and programmatic access
Field service runs across more than one system. VH3 AI brings third-party tools into the same operational model so mail, calendar, CRM, storage, and field systems add useful context to the graph.
### Native connections (in the platform)
[Native integrations](/native-integrations) are activated inside VH3 AI: OAuth handled for you, sync managed by the platform, health visible to admins. Typical categories:
| Category | Examples | What flows into the layer |
| ---------------- | -------------------------------------------------- | ------------------------------------------------ |
| Field management | BigChange (live), others on roadmap | Jobs, engineers, customers, worksheets |
| Communication | Gmail, Outlook, Slack, Teams, WhatsApp | Threads, alerts, context for briefings |
| Scheduling | Google Calendar | Per-user availability and planning context |
| CRM / finance | Pipedrive, Zoho, Xero, Stripe, Salesforce, HubSpot | Commercial context alongside operational history |
| Storage / docs | Drive, OneDrive, Dropbox, PandaDoc | Documents linked to accounts and work |
**Per-user connections** matter for agents tied to real people: an engineer's inbox and calendar, scoped to what they authorised, can inform briefings without exposing everyone's mail to the organisation.
**Organisation-level connections** matter for shared systems: one Xero or Slack workspace, one CRM, available to automations and reporting across the team.
### Programmatic access (for your agents and apps)
Everything the platform does internally is also available **programmatically**:
* **REST API** for search, jobs feed, sentinels, reports, Connie, cases, teams, and backfill tasks.
* **MCP server** so Claude Desktop, Cursor, and other MCP clients call the same tools Connie uses, with credentials handled server-side after JWT auth.
* **n8n node** (community and PRO) for workflow builders who want operations-friendly automation without writing a backend.
When email arrives or a calendar event is created, ingestion and **entity resolution** map people, domains, and addresses back to **contacts** in your model. That is how personal agents and shared automations stay aligned with operational truth across inboxes and calendars.
Design automations so **fast endpoints** (search, autocomplete, sentinels, jobs feed) handle triggers and filters, and reserve Connie or investigate for steps that need narrative. Predictable latency and visible AI cost follow naturally.
## Operations builders (no-code and low-code)
The citizen-builder pattern is how strong field service teams already work when they are not waiting on IT:
* An operations manager routes a **sentinel digest** to Slack when SLA performance slips.
* A contracts lead schedules an **account monthly report** to a client distribution list.
* A service coordinator creates a workflow when **engineer-flagged follow-ups** spike for one customer.
None of that requires a development team. It requires **templates**, **connectors**, and an intelligence layer that returns consistent, scoped data.
**Starting points:**
* [n8n node and templates](/n8n-node)
* [Agent kits: n8n agents](/agent-kits/n8n-agents)
* [Claude Projects for ops](/agent-kits/claude-projects)
## Coding agents on a secure substrate
Tools such as **Claude Code** and **Cursor** work best when they are not guessing your domain. They need:
1. A **stable API contract** (OpenAPI, consistent field names).
2. **Guardrails** (which endpoint for which question, what never to expose to end users).
3. A **tenant boundary** (`company_id`, `api_key`, no cross-customer leakage).
VH3 AI ships **Agent Starter Kits** for that: AGENTS.md, Cursor rules, MCP setup, and n8n prompts that encode field service routing (discovery vs synthesis vs sentinels).
Drop-in configuration so coding agents use VH3 endpoints correctly from day one.
### What coding agents should build
| Application | Discovery / data | Synthesis / action |
| ------------------------- | -------------------------------------- | -------------------------------------------------------------------- |
| Dispatch assist panel | `search/outcomes`, autocomplete | Optional Connie summary |
| Customer 360 internal app | Jobs feed, customer summary by contact | Reports, investigate |
| Slack ops agent | `sentinels/run` | Connie with citations ([observability](/guides/agent-observability)) |
| Partner portal | Scoped search by `contact_id` | Branded report export |
### Safe patterns
**Never call VH3 APIs from browser code.** Your `api_key` and `company_id` are server-side credentials. If they appear in a browser network request — even inside a fetch call in a React component or a bundled environment variable — they are visible to anyone who opens browser developer tools. Build a backend route that holds the credentials and proxies the call. The browser calls your backend; your backend calls VH3. This applies to every endpoint on `api:kP8T1CK7` and `api:YdihQNr3`. For browser-based apps, use [User Authentication (JWT)](/authentication#user-authentication) so users log in with email and password only, and no API key is ever involved in client code.
**Never expose internal identifiers** in end-user interfaces: internal company, job, contact, resource, or linkage keys. Use names, references, and addresses in UI copy. Keep IDs in server-side calls only.
**Contact-centric scoping.** Build navigation around customers (contacts). Places are addresses under that customer. Engineers are resources. This matches how account managers and dispatchers think.
**Timeouts.** Discovery endpoints are typically sub-second. `investigate`, report generation with narrative, and Connie tool loops need longer HTTP timeouts (often 20 to 25 seconds). Agent kits document recommended values.
### MCP: intelligence without middleware
The MCP server exposes tools such as search, investigate, sentinels, jobs feed, and reports. A coding agent can call operational discovery directly, then generate UI or workflow code around the responses.
See [MCP setup](/agent-kits/mcp-setup).
## Customer knowledge your agents can rely on
Builders should understand the **Customer Summary** knowledge object (see [Operational discovery](/guides/operational-discovery)):
* Seven **modular sections**, each independently searchable and rankable.
* **Refreshed** on a schedule or when job drift thresholds are met, so agents are not stuck with a one-off PDF.
* **Injected** into Connie sessions together with recent jobs since generation, so conversations start with current context.
Coding agents can call `POST /search/summary-sections` for thematic queries across accounts, or fetch a full brief per contact before rendering a custom account page.
## From signals to owned work
AI integration fails when insight has nowhere to go. VH3 AI pairs **detection** with **ownership**:
| Concept | Role |
| ------------------------ | ------------------------------------------------------------------------------------------- |
| **Sentinels** | Continuous pattern detection on the graph (no LLM at detection) |
| **Discovery** | Fast precedent, entity, and knowledge-section lookup |
| **Connie / investigate** | Cited synthesis and diagnostic narrative |
| **Cases** | Multi-step operational work (escalation, complaint, follow-up) with status and participants |
| **Teams** | Scoped groups for who owns which customers or regions |
**Example flow:**
1. Sentinel flags repeat attendance for a contact.
2. Automation runs `search/outcomes` for similar faults on that account.
3. Case opened: "Third fire panel callout in six weeks" with jobs linked as items.
4. Regional team notified; Connie drafts engineer briefing for the next visit.
Cases and teams are intentionally lightweight: enough structure to **close the loop** with status, participants, linked jobs, and ownership.
* [Cases API](/api-reference/cases)
* [Teams API](/api-reference/teams)
## Why the substrate makes coding agents viable
Prepared context is what makes coding agents useful in field service. Each session can start from enriched jobs, resolved accounts, and linked history.
VH3 AI front-loads **enrichment**, **multi-entity resolution**, and linking of jobs, customers, sites, and history at ingest. Coding agents then generate thin applications that call well-shaped endpoints. You are not paying an LLM to rediscover your operation on every click.
> Built to be built on. Your people, solving their own problems, on their own terms.
The platform is the layer your agents and applications sit on while your field system and IDE continue doing their jobs.
## Security and governance (builder-relevant)
If you are building any app that a user will open in a browser — even an internal tool, a partner portal, or a quick MVP — read [Deploying secure apps](/guides/deploying-secure-apps) before you ship. Coding agents in particular will produce working code that exposes credentials insecurely unless you give them explicit guidance on the frontend/backend split. The checklist on that page is the minimum bar for any user-facing app.
Builders should assume:
* **Data scoping** on every call (`company_id` + validated `api_key`). No API call can cross organisation boundaries.
* **Built-in user management and auth**: invite users, assign roles, issue JWTs. You do not need to build the auth layer yourself.
* **PII handling** aligned with your DPA: do not rebuild sensitive fields into public UIs.
* **Read-only field integration** by default; write-back only when explicitly agreed.
See [Authentication](/authentication) for the full credential surface map and [Deploying secure apps](/guides/deploying-secure-apps) for the deployment checklist.
## Choose your starting kit
| You are | Start here |
| ------------------------------ | ------------------------------------------------------------------------------------------------ |
| Ops lead, no code | [Claude Projects](/agent-kits/claude-projects), [n8n node](/n8n-node) |
| Technical ops / PM with Cursor | [AGENTS.md](/agent-kits/agents-md) + [Cursor rules](/agent-kits/cursor-rules) |
| Engineer building a product | [API overview](/api-reference/overview) + [Operational discovery](/guides/operational-discovery) |
| Agent in Claude Desktop | [MCP setup](/agent-kits/mcp-setup) |
## Related
Architecture narrative for technical buyers.
Connect inboxes, calendars, CRM, and storage.
Platform principles and sovereignty.
Keys, tenancy, and access.
# Compounding operational capability
Source: https://docs.vh3.ai/guides/compounding-operational-capability
How field service organisations build a learning loop between human judgment and operational intelligence — and why the substrate matters more than the model
# Compounding operational capability
Every platform shift changes what tools an organisation runs. The AI shift changes how an organisation **learns**.
In field service, that learning has always happened in two places at once. Your people carry judgment: which customer needs a careful call, which engineer knows the plant room, which fault description in a worksheet actually means something specific, which sentinel threshold has gone noisy. Your systems carry records: jobs, outcomes, sites, engineers, invoices, emails, certificates.
AI creates a cognitive loop between those two for the first time. Questions that used to require a report request, a spreadsheet, or someone with five years in the business can be answered in seconds — if the operational intelligence underneath is prepared, owned, and improving.
The durable opportunity is building a loop where human judgment and operational intelligence compound together — regardless of which model you use this quarter.
## Human judgment and operational intelligence
**Human judgment** is what your team already has: relationships with facilities managers, pattern recognition across accounts, trade knowledge, dispatch judgment, commercial instinct, and the ability to decide what matters when the data is ambiguous.
**Operational intelligence** is what your organisation builds in systems: enriched job history, resolved customers and sites, sentinel rules, case records, briefing templates, automation workflows, company preseeds, and the structured memory that survives when people move on.
As operational intelligence grows, human judgment becomes more valuable — because your people spend less time assembling context and more time applying judgment.
The account manager who used to spend a morning rebuilding the story before a review now walks in with evidence, job references, and time to decide what to do about it.
The operations lead who used to manually spot repeat-visit patterns now reviews sentinel findings, adjusts thresholds, and owns the cases that need a human call.
The field intelligence lead who used to chase exports now gardens workflows, tunes automations, and ships the next internal tool the operation actually needs.
Operational intelligence handles the legwork. Human judgment directs what gets built next.
## The learning loop
A field service operation that compounds capability runs a loop:
1. **Jobs and signals enter** — from the FMS, email, documents, integrations.
2. **Records are enriched and linked** — fault types structured, entities resolved, history connected.
3. **Intelligence is used** — Connie answers, sentinels fire, reports run, briefings go out, cases open.
4. **People review and act** — thresholds adjusted, ambiguous matches confirmed, cases closed with outcomes recorded.
5. **The substrate improves** — exclusions updated, preseeds refined, workflows tuned, the next question starts from a better foundation.
Each pass through the loop makes the next pass cheaper and more accurate. A sentinel that fires correctly three months in a row becomes a trusted signal. A briefing template that account managers actually use gets refined. A workflow that routes portal email correctly stops needing manual review.
This is institutional learning encoded in operational systems — not in a model vendor's training run.
You can offload a task. You can automate a briefing. You cannot offload the discipline of improving the loop.
## The sovereignty test
There is a practical test for whether your organisation owns its operational intelligence or rents it from a vendor:
**Can you change the model underneath without losing what your operation has learned?**
If your operational memory lives inside a black-box chat product, switching models means starting again. If your intelligence lives in a prepared substrate — enriched records, graph relationships, sentinel definitions, case history, automation logic — the model is interchangeable. Connie can run on your provider account through BYOK. Agent kits can point Cursor or Claude at the same API tomorrow. n8n workflows keep calling the same endpoints regardless of which LLM sits in the decision node.
The generalist model changes every six months. The operational veteran — five years of resolved jobs, tuned thresholds, accumulated cases — should not.
VH3 AI is built around that separation. The platform fee covers enrichment, graph, sentinels, and synthesis infrastructure. Model spend stays on your provider account, visible and portable. The intelligence compounds in your organisation's account.
## What compounds in your account
Operational intelligence that belongs to your organisation includes:
* **Enriched job history** — classified faults, structured outcomes, linked engineers, sites, and customers, up to five years loaded on day one.
* **Resolved entities** — customers, sites, and engineers connected across naming inconsistencies and source systems.
* **Sentinel definitions** — thresholds, scopes, and exclusions your team has tuned to match how the operation actually runs.
* **Cases and evidence** — investigations, linked jobs, participant decisions, and the record of what was done about a signal.
* **Automations and workflows** — n8n templates, routing rules, digest schedules, and integrations your field intelligence lead maintains.
* **Company preseeds and operating rules** — how your business wants Connie and agents to behave, refined as the operation changes.
This is the asset that gets harder for a competitor to replicate the longer you run it, because it encodes **your** operation's judgment over time.
## What your team must own
VH3 AI provides the substrate. The loop still needs people inside the business:
* **Direction** — which problems to solve first, which accounts need attention, which workflows are worth automating.
* **Gardening** — sentinel thresholds, triage taxonomies, exclusions, and preseeds that drift as the operation changes.
* **Review** — ambiguous entity matches, investigation conclusions, compliance-adjacent signals, and case outcomes.
* **Building** — the next report, workflow, briefing, or internal tool that removes a recurring manual step.
The [2027 blueprint](/guides/2027-blueprint) describes the person who often owns this loop: the field intelligence lead, close enough to the work to understand it, technical enough to build on the platform.
Organisations that invest in upskilling that person — or developing that capability across a small team — compound faster than organisations that treat AI as a subscription to finish.
## A frontier for operators, not just model vendors
Field service generates deep operational signal and deep operational judgment. Most of that value has never been encoded in systems that compound — it lived in people's heads, scattered spreadsheets, and FMS records that were never designed to learn.
When operational knowledge flows only into a handful of generalist models, operators risk hollowing out while a few platforms capture the returns.
Every field service organisation can own the loop that encodes **its** expertise — portable, inspectable, improvable — and ride each new model generation against that foundation.
That is what VH3 AI is built to be: a harness on the stack you already run, intelligence that compounds in your account, with human judgment at the centre of the loop.
How to organise for capability inside your operation.
How operational context is prepared before any question is asked.
Why traceability matters more than confidence in operational decisions.
APIs, automations, and agents that read the same prepared foundation.
How humans and agents work together on the same operational record.
The engineering work behind an accurate, live operational picture.
# Connie
Source: https://docs.vh3.ai/guides/connie
VH3 AI's flagship operations agent with long-running context, evidenced answers, and efficient use of your intelligence layer
# Connie
Connie is VH3 AI's flagship conversational agent: a field service operations specialist wired into your full intelligence layer. She reads the same enriched operational model as search, sentinels, reports, and automations, and she is built for real work: multi-turn reviews, account prep, diagnostics, and follow-through that depends on what was said five minutes ago.
How operators brief Connie: three principles, role playbooks, and session habits. Start here if you have not used Connie before.
Fast precedent search and entity resolution (no LLM). Connie calls these when she needs facts; she synthesises when you need narrative.
How to verify Connie's answers: tool outputs, citations, usage, and structured evidence.
Connie handles ambiguous questions and short prompts well. For operator habits that get the most out of her on harder asks, see [Working with your operation](/guides/working-with-your-operation).
## Connie on the harness
VH3 AI separates **discovery** from **synthesis**. Discovery handles fast lookup: search, autocomplete, feeds, and customer knowledge sections. Connie handles synthesis: explaining, comparing, investigating, briefing, and recommending with citations.
Connie is disciplined about when to spend tokens. Simple greetings and meta questions can be answered without a full tool loop. Analytical questions trigger the right operational tools. Heavy diagnostic work routes to investigation flows that return structured evidence, not guesswork.
That split is what makes the agent practical at scale: the expensive interpretation runs on **prepared** data (enriched once at ingest), not on re-reading raw field system exports every turn.
## Sessions: focused, managed, and recoverable
A Connie session is a conversation about one thing. Keep them concise and to the point. When the topic changes, start a new session.
Shorter, focused sessions perform better in three measurable ways:
* **Economics.** Token cost grows with the context you carry into each turn. A 40-turn thread that has wandered across three customers spends tokens re-reading its own history. A focused session does not.
* **Recall and answer quality.** A focused session keeps the model on the question. Long, drifting threads encourage the model to mix unrelated context into the answer.
* **Auditability.** Sessions are managed: stored, recoverable, searchable, and citable. A session per topic gives you a clean record of what was asked, what was answered, and what evidence was used.
**Session IDs are issued by the platform.** Do not invent them. Omit `session_id` on the first turn; the response returns a UUID to use on every subsequent turn in that thread. Between topics, drop the ID and let the platform issue a new one.
**Between sessions, start fresh.** A new topic, a new account, a new day's standup: omit the ID. Connie loads the right opening context (see below) automatically; you do not carry over yesterday's context or its token cost.
### How to start and continue a session
First turn, no `session_id`:
```json theme={null}
{
"company_id": "your-company-id",
"api_key": "your-api-key",
"message": "What recurring issues have we seen here in the last 90 days?",
"contact_id": "12345",
"user_name": "Sarah"
}
```
The response includes a `session_id` UUID. Pass it on every follow-up:
```json theme={null}
{
"company_id": "your-company-id",
"api_key": "your-api-key",
"message": "Which engineer has the best completion rate on those jobs?",
"session_id": "a1b2c3d4-e5f6-...",
"contact_id": "12345"
}
```
When the topic changes, omit `session_id` again. The platform issues a new one.
### Opening context on new sessions
When you start a session with a customer in scope, the server can inject:
* **Company operating context** (terminology, rules, and preferences your organisation configured).
* **Customer Summary** plus **recent completed jobs** since that summary was generated, so turn one is not stale.
You can still pass a `summary` from your app; the server enriches it when possible and reports how that block was built (see [Agent observability](/guides/agent-observability)).
### Recovery and search
Sessions are durable. Past sessions can be retrieved, listed, and searched via the [Connie API](/api-reference/connie). Start new threads freely; the platform preserves previous sessions as evidence.
### Contact-scoped by default
From a customer or job view, Connie defaults queries to that contact unless you ask a company-wide question. That matches how account managers and coordinators actually work, and it is another reason starting a new session per topic stays cheap: each one starts with the right scope already set.
## Memory that compounds
Connie benefits from the same **operational memory** as the rest of the platform:
* Jobs are **enriched once** (fault patterns, outcomes, links to customer, site, engineer, equipment).
* **Customer Summary** knowledge is stored in modular sections and refreshed on schedule or when job drift thresholds are met.
* **Tool outputs** from substantive calls in a session can be retained and recalled within that session so she does not repeat expensive lookups on follow-up turns.
* **Background compaction** runs on longer sessions: the platform periodically summarises earlier turns into a compact form so recall stays sharp without carrying the full raw history forward on every message.
This is **your organisation's intelligence layer getting richer continuously** and Connie reading that layer on every turn, including what happened earlier in the session.
## Efficient token use
Connie is built for production economics (especially with [BYOK](/pricing)):
* **Intent routing** classifies messages so lightweight turns can skip the full agent and tool suite.
* **Company-level prompt caching.** Shared company context (instruction blocks, tool definitions, organisation operating context) is cached across all users in your organisation. Every person on the team benefits from cache hits that earlier sessions already warmed. `cacheReadTokens` in the usage response shows how much of each turn was served from cache.
* **Compact tool results for efficient chat.** Feeds, search, and aggregates return trimmed shapes so the model is not fed empty fields and nested noise. Semantic search hits include `contactName`, `jobRef`, and visit dates so answers can name sites and cite references without extra lookups.
* **Discovery-first tools** (`search_outcomes`, `jobs_aggregate`, `job_feed`, autocomplete, customer summary sections) handle lookups without running narrative investigation unless the question requires it.
Every chat response includes **usage** (`inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheCreationTokens`) so you can see what a turn cost on your provider account.
## Fully evidenced answers
Connie is instructed to **cite job references and names**, never internal database IDs in user-facing text. Behind the narrative:
* **Investigation** returns headline findings, ranked recommendations, confidence, and **evidence** tied to real job references.
* **Search and feed tools** return graph-linked records, not orphaned text snippets.
* **`toolCallOutputs`** on the API response exposes the structured JSON from each tool invocation in that turn, so your UI can render tables, charts, and drill-downs from evidence.
If a tool fails, she is instructed to say so and offer another angle, not invent numbers.
Treat the assistant message as the summary. Use `toolCallOutputs`, job references in the text, and your own drill-down into discovery endpoints as the source of truth for anything that affects commercial or safety decisions.
## What Connie can do
Connie can answer any question the underlying data supports. Examples by shape of work:
### Performance and trends
* "Which engineers had the best first-time-fix rate this quarter?"
* "How is Mike performing compared to last month?"
* "Show me the top five engineers by SLA punctuality."
* "How many jobs did we complete yesterday versus the same day last week?"
### Sites and customers
* "What happened at the Manchester site last week?"
* "Which customers have the most repeat visits?"
* "Give me the job history for this account."
* "How does this customer's failure rate compare to the company average?"
### Diagnostic and precedent
* "Has anyone seen this fault before?" (with a description)
* "What usually fixes a boiler intermittent lockout?"
* "Find similar jobs to this one."
* "Why are roofing jobs running late?" (investigation-style synthesis)
### Operational actions (where enabled)
Depending on your setup and integrations, Connie can also drive **email drafts**, **notifications**, **briefings**, **account reports**, **presentations**, and lookups into connected systems (CRM, mail) through the same connected platform capabilities. See the [Connie API](/api-reference/connie) for endpoints and fields.
## Working on your behalf (without a prompt)
Most of Connie's value lands without anyone typing. Connie reads the same signals the platform watches continuously, so she can pick up work before the operator asks.
* **Sentinels** detect patterns 24/7 with near-zero AI cost at detection: repeat visits, SLA drift, dormant customers, performance slips. See [Sentinels](/guides/sentinels).
* **Cases** turn signals into owned work with status, participants, and linked jobs. Connie can open a case for a sentinel trigger, attach the relevant evidence, and draft the brief the assignee will read.
* **Teams** route cases to the right people: regional, portfolio, or functional groups own customers and sites so nothing sits in a generic queue.
A typical autonomous loop:
1. Sentinel flags repeat HVAC callouts at an account.
2. Automation opens a case, runs discovery for similar precedents, and asks Connie for a draft brief.
3. The regional team finds the case ready, with citations, when they next look at the queue.
The operator's job is to steer and verify, not to push the platform into motion.
Autonomous loops depend on your tier, enabled integrations, and configured case/team rules. During onboarding, decide which sentinel findings should create cases automatically and which should stay as digest items for human review.
## Specialist capabilities
Connie orchestrates **focused sub-tasks handled automatically** for specialist work (for example structured email generation and deeper analytical passes). You interact with one assistant; the platform routes complex sub-tasks without you managing multiple agents.
## Tips for effective questions
"Last 30 days" beats "recently." Connie infers ranges when she can, but explicit dates reduce ambiguity.
Use engineer names, site addresses, or customer names when you know them. Autocomplete resolves fuzzy input; exact names are faster.
Same `session_id` for the same topic. "Tell me more about the third one" or "What caused that?" When the topic changes, start a new session.
Ask for tables, comparisons, or bullet recommendations. "Compare Mike and Sarah this quarter" works well.
## Field service playbook
| You want | Example prompt | What Connie typically does |
| ------------ | -------------------------------------------------------- | ------------------------------------------ |
| Quick count | "How many completed jobs last week?" | Aggregation with sensible time axis |
| Account prep | "Summarise risk for this customer" | Customer summary + recent jobs + synthesis |
| Precedent | "Similar callouts for intermittent lockout" | Semantic search on outcomes or intake |
| Root cause | "Why is SLA slipping in the North?" | Investigation with cited evidence |
| Briefing | "What should the engineer know before tomorrow's visit?" | Job detail, weather, history, narrative |
## Building with Connie
| Surface | Best for |
| --------------- | -------------------------------------------------------------------------- |
| **VH3 Connect** | Embedded ops UI with generative components from `toolCallOutputs` |
| **API** | Custom portals, mobile, partner apps |
| **MCP** | Claude Desktop, Cursor, coding agents ([MCP setup](/agent-kits/mcp-setup)) |
| **n8n** | Slack or Teams assistants ([n8n Agent Prompts](/agent-kits/n8n-agents)) |
Use [Agent observability](/guides/agent-observability) when you build UIs or compliance workflows that must show **why** an answer was given.
## Related
Request fields, sessions, voice, and history search.
Why relational, semantic, structured, and temporal memory matter.
Discovery vs synthesis for builders and integrators.
Tenant keys, JWT for interactive apps, BYOK.
# Deploying secure internal apps
Source: https://docs.vh3.ai/guides/deploying-secure-apps
Governance, authentication, and deployment patterns for apps built on the VH3 AI intelligence layer
# Deploying secure internal apps
This guide is for **IT leads, technical owners, and architects** approving or shipping internal apps on top of VH3 AI. It complements [Building on the layer](/guides/building-on-the-layer), which covers the builder patterns. This page is the governance and deployment view: how access works, what to harden, and which tier you actually need.
## 1. What "built on the substrate" means
VH3 AI is one operational model per organisation. Every surface, whether VH3 Connect, a custom portal, a Slack agent, a mobile wrapper, or a coding agent, reads the same intelligence layer: discovery, sentinels, Connie, cases.
That means:
* **No bespoke data layer per app.** Your portal and your Slack agent agree on what "a job at Berwyn House" is, because both read the same model.
* **Thin apps are appropriate.** Internal apps focus on workflow and UX; the substrate handles enrichment, resolution, and synthesis.
* **Switching surfaces is cheap.** Replacing a UI does not invalidate the operational picture.
## 2. Access patterns (choose one)
Pick the pattern that matches the surface. Do not mix.
| Pattern | When to use | Credential | Where it runs |
| ----------------------- | ----------------------------------------------------------- | ---------------------------------------------------- | -------------------------------------- |
| **VH3 Connect** | You want the managed UI, users, roles, cases out of the box | JWT (managed by VH3 Connect) | Browser, mobile |
| **Custom app** | You need bespoke UI/UX for your operators or customers | Per-user JWT ([User Auth](/api-reference/user-auth)) | Browser, mobile |
| **Automation** | n8n workflows, back-office scripts, integrations | `company_id` + `api_key` | Server only |
| **Coding agents / MCP** | Cursor, Claude, Claude Code, MCP-compatible clients | JWT ([MCP setup](/agent-kits/mcp-setup)) | Developer machines, server-side agents |
**Rule:** `api_key` is a server credential. It must never appear in a browser, mobile bundle, or anything a customer can inspect.
## 3. Security model (IT checklist)
The platform ships with the controls below. Your job is to use them correctly.
### Data scoping and user management
* All API calls are scoped by `company_id`. Tenant resolution happens server-side, no API call can cross organisation boundaries.
* The platform ships with built-in user management: invite users, assign roles, organise teams, and issue JWTs without building any of that yourself. See [Users and teams](/guides/users-and-teams).
* Dedicated, isolated infrastructure is available on Enterprise plans.
### JWTs and sessions
* Login returns a JWT valid for **24 hours**. Refresh issues a new 24-hour token.
* Plan a refresh policy: silent refresh during active sessions; re-login at idle thresholds your security team is comfortable with.
* Do not store the JWT in non-HTTP-only storage if you can avoid it. Treat it as a session credential.
### Internal IDs and PII
* Internal IDs (`company_id`, `job_id`, `contact_id`, `resource_id`) belong on the server.
* UI should show **names and job references**, not internal IDs (Connie follows the same rule, see [Connie](/guides/connie)).
* PII in UI is a product policy decision. Decide once, enforce in the app layer.
### BYOK (Connie and agents)
* Conversational AI runs on **your model provider key**.
* Cost lands on your provider account at your contracted rate. No vendor margin.
* See [Pricing](/pricing) and [Connie](/guides/connie) for the BYOK model.
### Timeouts
* **Discovery** completes sub-second. Set tight client timeouts.
* **Connie and `/investigate`** are multi-step. Plan for **20 to 25 seconds**, longer on cold caches.
* Apps should surface a loading state for synthesis; do not pretend it is instant.
## 4. Building a custom app: the right architecture
If you are building a dashboard, a partner portal, or any browser-based application on top of VH3 AI, the architecture below is the minimum required before connecting to real customer data. Coding agents will produce working code without this separation — but that code will be insecure.
### The required split
Your app needs two distinct parts:
* **Frontend** (what runs in the browser): handles display, navigation, and user interaction. Contains no credentials. Makes API calls only to your own backend.
* **Backend** (a server you control): holds credentials, validates identity, and makes all calls to the VH3 API. The browser never calls VH3 directly.
```
Browser
│ calls your backend only (no VH3 credentials)
▼
Your backend server
│ validates JWT → calls GET /auth/me → gets company_id
│ makes VH3 API call with api_key from environment variable
▼
VH3 API (api.vh3connect.io)
```
A proxy that simply forwards the `api_key` from an environment variable to the browser in a response header, or that passes it through as part of a client-visible request, is not a backend. The credential must stay on the server at all times and must never appear in any response the browser can read.
### Authentication flow for a custom app
1. User visits your app and is redirected to your login page.
2. Your login page posts `email` and `password` to **your backend** (not directly to VH3).
3. Your backend calls `POST https://api.vh3connect.io/api:lBQnyyZL/auth/login` and receives the `authToken`.
4. Your backend sets the `authToken` as an `httpOnly` secure cookie on the response. The browser stores it automatically and sends it on every subsequent request. The token itself is never accessible to JavaScript.
5. On every protected request from the browser, your backend reads the cookie, calls `GET https://api.vh3connect.io/api:lBQnyyZL/auth/me` with the token to validate it and retrieve the user's `company_id`.
6. Your backend uses the verified `company_id` and the `api_key` from its environment variables to call the VH3 API. It returns only the data the frontend needs.
The `company_id` that scopes your VH3 API calls must always come from the `GET /auth/me` response on the server. Never accept it from the browser — a user could send any value in a request body or query parameter.
### What this looks like in practice (Node.js / Express)
```javascript theme={null}
// Backend route — runs on your server, never in the browser
app.get('/api/jobs', async (req, res) => {
const token = req.cookies.vh3_token;
if (!token) return res.status(401).json({ error: 'Not authenticated' });
// Validate the token and get the user's company
const meResponse = await fetch('https://api.vh3connect.io/api:lBQnyyZL/auth/me', {
headers: { Authorization: `Bearer ${token}` },
});
if (!meResponse.ok) return res.status(401).json({ error: 'Session expired' });
const { company_id } = await meResponse.json();
// Call VH3 with server-side credentials
const jobsResponse = await fetch('https://api.vh3connect.io/api:kP8T1CK7/jobs/feed', {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
// company_id and api_key stay on the server
// pass them as query params or body per the API spec
});
// Return only what the frontend needs — strip internal IDs
const data = await jobsResponse.json();
res.json(data);
});
```
### Environment variables and deployment
Store credentials as server-side environment variables only. On Railway, Render, Fly.io, or any similar platform, set these in the service settings — not in any file committed to your repository:
```
VH3_COMPANY_ID=your-company-id
VH3_API_KEY=your-api-key
```
The frontend service should have zero secrets in its environment. If a coding agent suggests adding `NEXT_PUBLIC_VH3_API_KEY` or any credential prefixed for browser exposure, that is a mistake — reject it.
### CORS
Lock your backend to accept requests only from your frontend's exact origin:
```javascript theme={null}
app.use(cors({
origin: 'https://your-frontend-domain.railway.app', // your frontend origin only
credentials: true, // required for httpOnly cookie support
}));
```
When you add a custom domain later, update this to the production domain. Do not use `origin: '*'` at any point in a user-facing deployment.
## 5. Typical internal apps
| Internal app | Auth pattern | Discovery surfaces | Synthesis surfaces | Ownership |
| ------------------------------- | ------------------------------- | ------------------------------------------ | ------------------------------------- | ---------------------------------- |
| Dispatch assist | VH3 Connect or custom JWT app | `/search/outcomes`, `/search/autocomplete` | Connie for "who has done this before" | Cases assigned to dispatch team |
| Customer 360 portal (internal) | Custom JWT app | Summary sections, jobs feed | Connie account brief | Cases per regional team |
| Slack ops agent | n8n on server (`api_key`) | Discovery + sentinels | Connie for narrative replies | Cases linked from Slack messages |
| Partner / sub-contractor portal | Custom JWT app, restricted role | Scoped jobs feed | Connie with restricted toolset | Cases visible only to partner team |
Each pattern reuses the same substrate. The differences are UX and the role mapping in front of it.
## 6. Users, teams, and cases as governance
Governance on this platform comes from using the user, team, and case model correctly.
* **Users and roles** ([Users](/api-reference/users), [User Auth](/api-reference/user-auth)) decide who can sign in and what they can do.
* **Teams** ([Teams](/api-reference/teams)) decide what each user sees and owns.
* **Cases** are the audit surface: status, participants, linked jobs, activity timeline. On Connect tier, cases are first-class.
The end-to-end loop:
1. A **sentinel** detects a pattern continuously (near-zero AI cost at detection).
2. A **case** is opened against the team that owns the affected customer or region.
3. The team uses **discovery** for precedents and **Connie** for a brief.
4. Decisions, replies, and follow-ups are logged against the case.
See [Building on the layer](/guides/building-on-the-layer) for the sentinel-to-case flow in code, and section 4 above for the custom app architecture that puts this in a secure deployment.
## 7. Tier and capability map
| Tier | Best for | Auth surfaces | Notable governance features |
| ------------------ | -------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------ |
| **VH3 API** | Builders integrating BigChange and automation only | `company_id` + `api_key` | No intelligence layer in this tier |
| **VH3 Core** | Operational AI, single team | API key, JWT for custom apps, BYOK | Intelligence layer, semantic search, reports, sentinels |
| **VH3 Core+** | Multi-team operations needing role mapping | All Core + per-user OAuth | **User-based permissions, role mapping**, native integration layer |
| **VH3 Connect** | Managed UI, multi-agent governance, cases | All Core+ + Connect UI | VH3 Connect platform UI, case management, audit trails, multi-agent governance |
| **VH3 Enterprise** | Dedicated 90-day programme, custom commercials | All Connect + bespoke | Programme manager, custom controls |
Choose the access point that matches your UI, permission, and governance needs. A team that already has a strong front-end may start on Core and build its own UI. A team that wants to skip UI work uses Connect. The substrate is the same.
See [Pricing](/pricing) for the full feature matrix.
## 8. Deployment checklist
Before launching an internal app on the layer:
* [ ] Auth choice is explicit (Connect / JWT custom / server `api_key` / MCP JWT).
* [ ] `api_key` never appears in client code, browser bundles, or mobile binaries.
* [ ] JWT refresh policy is implemented; idle and absolute session limits are agreed with security.
* [ ] CORS allowlist is restricted to your app origins.
* [ ] Client timeouts: short for discovery, 20 to 25 seconds for synthesis.
* [ ] Role mapping is configured for the surfaces the app exposes (Core+ if you need bespoke roles).
* [ ] Teams are created and linked to the customers, sites, or regions they own.
* [ ] Connie answers in commercial or safety contexts route through [Agent observability](/guides/agent-observability) for evidence standards.
* [ ] Generative UI components render structured tool outputs from scoped, authenticated API responses only.
* [ ] PII and internal ID policy enforced in the app layer; UI shows names and job refs only.
* [ ] BYOK key set per environment; cost dashboards monitored on your provider account.
* [ ] Case ownership defined for each sentinel that the app surfaces.
## Related
Full credential surface map: VH3 AI Intelligence, BigChange, JWT.
Roles, invites, team scoping, Core+ permissions.
Builder patterns for citizen builders, coding agents, and integrations.
Coding-agent and MCP-client access with JWT.
Evidence standards for commercial and safety-critical answers.
Tier feature matrix and BYOK economics.
# Generative UI
Source: https://docs.vh3.ai/guides/generative-ui
A drop-in React component library that renders VH3 AI tool outputs as polished operational interfaces, without any host configuration
# Generative UI
The VH3 AI platform returns structured tool outputs alongside every Connie answer, every report, every investigation, and every customer summary. That structure is the foundation for what we call generative UI: a single contract between the intelligence layer and the surfaces your team works from, so the same operational answer renders consistently in a dashboard, an internal tool, a custom application, or an AI-coded prototype.
The `@vh3/field-service-ui` package is the reference implementation of that contract. It is a self-contained React component library, designed to drop into any React application without configuration, that takes a VH3 AI tool response and renders the appropriate operational interface automatically.
**Preview.** The `@vh3/field-service-ui` package is in preview. The components, theming system, and contracts shown below are the targeted release surface. Get in touch with VH3 AI if you would like to use it before the public release.
## Why this exists
Most AI products either return prose or return raw JSON and leave the rendering problem to the consumer. Both create friction in field service operations.
Structured UI lets a coordinator drill into underlying jobs, verify numbers, and compare the picture across accounts without reading raw JSON or parsing a paragraph by hand.
The generative UI package solves both. The intelligence layer returns a structured payload. The component library knows how to render that payload. The result is a polished operational interface that looks the same in every application built on the layer, with no custom UI development required.
## The contract
The pattern is simple: one tool invocation produces one structured payload, which maps to one renderer.
```tsx theme={null}
import { ToolRenderer } from "@vh3/field-service-ui";
;
```
The renderer dispatches automatically based on the tool name. An investigation response renders as an evidence-cited investigation card. A customer summary response renders as a sectioned customer brief. A report generation response renders as a full dashboard layout. The same JSON your agents already receive becomes a complete interface.
## What is in the package
The library includes a set of dedicated components for the most common operational outputs:
| Tool name | Component rendered |
| ------------------------------------------------------ | ------------------------------------------------------ |
| `jobs_aggregate` | Stats, chart, or comparison card, chosen automatically |
| `job_lookup`, `job_feed` | Data table |
| `job_detail` | Job detail card |
| `weather_check`, `weather_for_job`, `weather_for_site` | Weather widget |
| `autocomplete` | Option list |
| `investigate` | Investigation card with evidence list |
| `generate_report` | Dashboard layout or composite report |
| `generate_summary` | Customer summary with seven sections |
| `contact_snapshot` | Composite contact report |
| `search_outcomes`, `search_intake` | Data table |
| `case_report` | Case report card |
Each component is also exported individually if you want to render a specific layout without going through the dispatcher.
## Live components
Browse the full component catalogue:
Live, interactive component gallery covering every component, story variant, and rendered tool output the library produces.
A selection of representative components below.
### Dashboard layout
The `DashboardLayout` component composes a full operational report from a `generate_report` response. Morning briefings, midday updates, weekly reviews, and account monthlies all render through this single layout.
### Investigation card
The `InvestigationCard` renders an `investigate` response as a headline, confidence score, recommendations, and a cited evidence list. The same component handles high, medium, and low confidence outputs.
### Customer summary
The `CustomerSummary` component renders the seven-section customer knowledge base in a single navigable interface, suitable for account reviews and pre-call briefings.
### Job detail card
The `JobDetailCard` renders a single job lookup as a complete operational record: status, timing, engineer, site, and outcomes.
### SLA gauges
Compact, glanceable visualisations for SLA performance, suitable for embedding in dashboards or briefing emails.
## Drop into any React application
The package ships with zero host configuration. All styles, fonts, and runtime dependencies are bundled inside the library. The only peer dependency is React.
```bash theme={null}
npm install @vh3/field-service-ui
```
```tsx theme={null}
import "@vh3/field-service-ui/style.css";
import { ToolRenderer } from "@vh3/field-service-ui";
function OperationsView({ apiJson }) {
return (
);
}
```
It works identically in Next.js, Vite, Create React App, Remix, Bolt, Base44, or any AI coding assistant scaffolding. There is no extra styling setup to copy, no font loading to configure, and no theme provider to wrap.
Use the package inside authenticated apps that enforce the same scoping rules as the API. Do not expose raw tool payloads or internal IDs in public portals without applying your access, PII, and tenant-isolation policy. See [Deploying secure apps](/guides/deploying-secure-apps).
## Custom theming
The package ships with the VH3 dark theme by default, but the visual identity is fully customisable through CSS variables.
**Option A: edit a copied config file.**
```bash theme={null}
cp node_modules/@vh3/field-service-ui/dist/theme/vh3-ui.config.css ./styles/vh3-theme.css
```
Adjust the `--vh3-*` variables, then import after the main stylesheet:
```tsx theme={null}
import "@vh3/field-service-ui/style.css";
import "./styles/vh3-theme.css";
```
**Option B: generate a theme at runtime.** This path is designed for rapid customisation and dynamic theming.
```tsx theme={null}
import { createTheme, injectTheme } from "@vh3/field-service-ui";
const css = createTheme({
background: "#0D1117",
accent: "#FF6B00",
fontSans: "'JetBrains Mono', monospace",
});
injectTheme(css);
```
The same components carry your visual identity without any source modification.
## Why this matters for builders
A coordinator's dashboard, a partner portal, an internal account review tool, and an AI-coded prototype can all render the same operational answer in the same way. That consistency is what makes the intelligence layer practical to build on at scale.
The platform returns the answer once. The component library renders it everywhere. Your team focuses on the operational workflow around it, not on rebuilding the rendering layer for every surface.
This is the visual contract for VH3 AI. As the platform evolves, the package evolves with it. New tool types ship with new renderers. New layouts ship with new components. Every consumer of the intelligence layer gets the upgrade automatically.
## Related
Full live preview of every component and variant.
The structured tool outputs this library renders.
Where the package sits in the broader builder story.
Response shape returned by the Connie tool surface.
# Intelligence in the agent era
Source: https://docs.vh3.ai/guides/intelligence-in-the-agent-era
Why field service operations need a harness on the stack they already run
# Intelligence in the agent era
Something important is settling in the market, and field service leaders are feeling it before the vocabulary catches up.
AI is changing **where work happens**, **how much output gets produced**, and **what "good" looks like** when anyone can draft an analysis, a workflow, or an internal tool in an afternoon. The field service management systems and the people who run them are still central. What shifts is the intelligence layer on top.
The organisations pulling ahead chose a **foundation**: persistent operational intelligence that humans and agents can trust together, sitting on top of the field service and business tools they already pay for.
That foundation is what VH3 AI is built to be.
## The paradox worth understanding
There is a pattern showing up in every AI-forward operation, including our own customers and partners:
**More automation creates more human work.**
The work that actually matters:
* Reviewing and approving what agents propose before it affects a customer or a compliance record.
* Gardening the automations and thresholds so alerts stay trustworthy.
* Building the systems that let non-specialists ask safe questions without flooding specialists with noise.
* Turning detected patterns into **owned follow-through** with cases, teams, and briefings.
VH3 AI is designed for that reality. Sentinels surface signals. Cases and teams assign ownership. Connie synthesises with citations. Your people steer and verify the loop.
When evaluating AI for field service, look for a clear approval and ownership model: who reviews the signal, who owns the case, and where the evidence is recorded.
## The SaaS stack you run is an asset
Field service runs on systems of record: your FMS, your finance tools, your CRM, your inboxes, your comms channels. Those investments stay in place. Agents add new demand for clean context, stable APIs, and clear ownership.
The real work is making your **existing stack agent-ready and human-ready at the same time**:
* The FMS remains where jobs are dispatched and completed.
* The intelligence layer holds the **enriched, linked, always-current picture** of what those jobs mean across history, people, sites, and outcomes.
* Automations route insight to Slack, Teams, email, or custom apps you control.
* Conversational AI runs on **your** model provider account ([BYOK](/guides/connie)), with no hidden token markup.
VH3 AI connects alongside BigChange (and every other platform on our integration roadmap). Connect once. Let the intelligence compound on your side of the contract.
**Data sovereignty.** Your enriched operational intelligence is scoped to your organisation and portable. The platform fee covers the layer; agent token spend stays visible on your provider account. See [Pricing](/pricing) and [Introduction](/introduction).
## Two ways your team will work (and one foundation underneath)
Operational AI is settling into two durable patterns. Most organisations will use **both** within twelve months.
### 1. The shared operational agent
One maintained agent (or a small, governed set) that many people use for async questions, digests, triage outcomes, and operational lookups.
Typically this lives where work already coordinates: **Slack**, **Teams**, or **VH3 Connect**. It needs an owner: someone inside your business (or ours during onboarding) who maintains thresholds, routing rules, and exclusions so the agent stays accurate as the operation changes.
VH3 AI supplies the brain for that agent: Connie, sentinel digests, email triage, deterministic search and aggregates, and n8n templates that wire channel mentions to cited, evidence-backed answers.
### 2. The personal work harness
Individuals doing knowledge work in **coding agents**, **Claude Projects**, or similar environments: drafting briefings, exploring accounts, building light internal tools, preparing leadership reviews.
The winning move is pointing that harness at **prepared operational context** so the model draws from your actual operational record in every session.
That is exactly what [Agent Starter Kits](/agent-kits/overview), the [MCP server](/agent-kits/mcp-setup), and the [REST API](/api-reference/overview) are for: your tools stay current; your operation stays authoritative on VH3 AI.
**One foundation, many surfaces.** Connect, Connie, n8n, MCP, and custom apps all read the same intelligence layer. Nothing forks into a separate integration database.
## Prepared context beats prompt engineering
The gap between AI that impresses in a demo and AI that holds up in dispatch, account management, or compliance is almost always **what the system knew before it acted**.
Classic retrieval works for simple lookups: search raw records at question time, hand fragments to a model. It struggles when a question crosses history, people, patterns, and accounts at once. It is expensive to repeat, and it goes stale fast.
VH3 AI is built around **assembly before inference**:
| Memory | What it holds |
| -------------- | -------------------------------------------------------------------------- |
| **Relational** | Jobs, engineers, sites, customers, outcomes, linked and traversable |
| **Semantic** | Faults and notes by meaning, not keyword luck |
| **Structured** | Enriched records, compact and ready for any consumer |
| **Temporal** | Sentinels watching continuously, surfacing signals before someone searches |
Together they form a **synthesis layer**: operating context for briefings, investigations, and agents, delivered as a prepared picture with linked evidence.
[Read how the intelligence layer works →](/intelligence-layer)\
[Why context is everything →](/guides/why-context-matters)
## Software for humans and agents together
Operational software that works for both humans and agents runs on a single truth:
* Humans see names, references, citations, and approval surfaces.
* Agents call fast, deterministic endpoints for lookups, and synthesis endpoints where narrative and judgment are needed.
* Side effects (cases opened, digests sent, triage decisions) are visible and auditable.
VH3 AI ships typed [generative UI components](/guides/generative-ui) for that reason: structured JSON from Connie and other tools maps to investigation cards, SLA gauges, and report sections your team can **read, challenge, and act on**.
[Agent observability →](/guides/agent-observability)
## How roles shift
AI drives down the cost of **generic** output: boilerplate summaries, template analyses, undifferentiated dashboards. What stays genuinely hard:
* Knowing which customer account is about to churn before the complaint arrives.
* Understanding how your engineers describe faults in the field.
* Deciding which triage rules protect life-safety work.
* Judging whether a sentinel threshold has become too noisy to trust.
| Role | What gets easier | What becomes more valuable |
| ------------------------------- | ------------------------------------------- | --------------------------------------------- |
| **Operations leaders** | Digests, triage, precedent lookup | Owning thresholds, cases, and service quality |
| **Account / contract managers** | Customer knowledge, scheduled reports | Judgment on risk, escalation, and narrative |
| **Dispatch and coordinators** | Briefings, search, Connie Q\&A | Exception handling and SLA trade-offs |
| **Transformation / PM** | Shipping workflows and light apps with kits | Choosing what to build and verifying fit |
| **Design / CX** | Generative UI from structured intelligence | Distinctive experiences that stand apart |
The [2027 blueprint](/guides/2027-blueprint) describes the single person who compounds this inside your organisation: the **Field Intelligence Engineer**, close to the operation, fluent in n8n and agent kits, responsible for the shared agent and the automations that embed intelligence into how you run.
What you need is **one bridge** and a prepared foundation for the tools and automations your team will build next.
## Ride the models
Model capabilities will keep shifting. Prices will move. New harnesses will appear. The organisations that stay ahead keep their prepared operational record current and ride each new model generation against it:
1. Connect the FMS and let enrichment compound.
2. Run a [discovery sprint](/quickstart) on real history.
3. Stand up sentinels and one shared agent pattern.
4. Drop [Agent Starter Kits](/agent-kits/overview) into the tools your team already uses.
5. Open [cases and teams](/guides/users-and-teams) so insight becomes owned work.
VH3 AI is committed to being the operating harness for that work. Better models arrive and your graph, rules, and automations stay. Field systems change and the layer reconnects. Custom software gets built on a domain model that already speaks field service.
[Building on the layer →](/guides/building-on-the-layer)
## What to do next
Connect your operation and see what the intelligence layer produces on your own data, before a long commitment.
How to organise for capability: VH3 AI, n8n, coding agents, and the Field Intelligence Engineer.
How operators use Connie, discovery, and sentinels day to day.
If your operation runs on BigChange, start here.
MCP, Cursor, Claude Code, and Claude Projects, fluent on VH3 from day one.
Visits enriched, unlimited users, BYOK for conversational AI.
***
The practical next step is to run the discovery sprint on real operational history, then choose one shared agent or sentinel workflow to put into the weekly operating rhythm.
**Field service needs intelligence that compounds: on the stack you already run, for the humans and agents who run it.**
# Keeping the graph current
Source: https://docs.vh3.ai/guides/keeping-the-graph-current
The engineering challenges behind maintaining an accurate, live operational intelligence graph — and how VH3 AI approaches them
# Keeping the graph current
An operational knowledge graph is most valuable when it reflects the operation as it actually is — not as it was at the time of the last export.
That is a harder engineering problem than it sounds. Field service operations never stop. Jobs complete while new ones open. Engineers join and leave. Customers change names, acquire subsidiaries, and close sites. Contracts expire. Certificates lapse. The same underlying fault gets described twenty different ways by twenty different engineers over five years.
The challenge is not building the graph once. It is keeping it accurate continuously.
This page describes how VH3 AI approaches that challenge, where the real complexity sits, and what it means for how the intelligence behaves in your operation.
## Continuous ingestion, not periodic extraction
Most data integrations work on a schedule. Extract the data once a day, or once a week, transform it, load it, and proceed. The result is always a picture of the past — a snapshot from the last time the job ran.
Field service operations do not wait for scheduled jobs.
A job that closes at 17:47 on a Thursday needs to be enriched, linked to the right customer and site, and available for a Friday morning account review. A compliance certificate that expired yesterday needs to surface today. An engineer who just completed a job at a site with a three-visit history needs that history in the briefing before the next van leaves.
VH3 AI processes operational data continuously. Every new job, updated contact, changed worksheet answer, or closed record flows through the enrichment pipeline on arrival. The graph does not accumulate a backlog. The operational picture stays current because the system was designed around continuous ingestion from the start, not retrofitted to it.
## Staleness and the relationship lifecycle
Adding new data to a graph is straightforward. Knowing when old data has become untrue is the harder problem.
Relationships have a lifecycle. An engineer who attended twenty sites last year may have left the business. A customer who was active across six locations may have closed two of them. A certificate linked to a site may have expired. A contract that linked a set of jobs to a commercial relationship may have ended.
All of these changes affect the meaning of data that was previously correct. A stale relationship is not just an outdated record — it changes what the graph says about your operation today. An engineer performance pattern that includes an engineer who left six months ago is a pattern built on incomplete context. A site risk flag that does not account for a closed location is a false positive.
VH3 AI builds staleness tracking into the relationship model directly. When a relationship ends — an engineer leaves, a site closes, a contract expires — that information is recorded in the relationship itself, not by deleting the data. Historical patterns stay accurate because the history is preserved. Current analysis stays accurate because it knows what is still active.
This means the graph can answer both questions: what was true in Q3 2024, and what is true now.
## Candidate selection and entity resolution
When a new job arrives in the enrichment pipeline, it does not arrive pre-labelled with a clean customer identifier, a resolved site reference, and a confirmed engineer assignment. It arrives with the fields that whoever created the record happened to fill in — which may be a partial name, an address formatted differently from every previous record, an engineer reference that matches three entries in the system.
The graph has to pick the right candidate. At volume. Continuously.
Entity resolution — deciding that "Tesco PLC", "Tesco Stores Ltd", and "Tesco Express Watford High St" are the same customer — is a solved problem in simple cases and a genuinely hard problem in operational data at scale.
VH3 AI uses a layered approach to candidate selection:
* **Structural signals:** field-level matches, reference codes, and identifier overlap
* **Semantic similarity:** meaning-based comparison of names, addresses, and descriptions that handles abbreviations, misspellings, and formatting inconsistencies
* **Historical match rates:** how previous records from this source have resolved, used to weight confidence in ambiguous cases
* **Confidence scoring:** every resolution carries a confidence level, and low-confidence resolutions are flagged for review rather than silently committed
Resolution is not perfect. Operational data is genuinely ambiguous in some cases. When that happens, the system surfaces the ambiguity rather than committing a guess. Those records sit in a review queue where a human can confirm or correct. Every confirmed or corrected resolution improves the logic for similar cases going forward.
## Graph health monitoring
A knowledge graph that nobody monitors degrades silently.
Isolated nodes accumulate as ingestion finds records that do not resolve cleanly to existing entities. Relationship chains break when a source system changes its data structure and the mapping logic is not updated. Clusters that should be connected drift apart as new data arrives and the resolution thresholds that worked six months ago no longer fit the pattern of incoming records.
None of this announces itself. The graph keeps returning answers. Those answers quietly become less accurate.
VH3 AI runs continuous health checks against the graph to catch degradation before it affects operational output:
* **Isolation checks:** nodes that should be connected to the main graph but are not
* **Orphaned relationships:** links where one end has been deleted or resolved away
* **Resolution drift:** clusters where the rate of low-confidence resolutions is increasing, indicating the logic may need recalibration
* **Staleness alerts:** relationships and records that have not been updated in longer than expected, given the pace of the connected source
When a health check flags an issue, it surfaces to the platform team before it affects answers. Some issues resolve automatically as new data arrives and corrects a previous resolution. Others require deliberate intervention — a mapping update, a threshold adjustment, or a manual correction.
This monitoring is not visible to most users day to day. It is the engineering work that makes the operational output trustworthy.
## Compliance-adjacent checks
Field service operations include work where the accuracy of the underlying data is not just operationally important — it has safety or regulatory significance.
Gas certificates. Electrical test records. Fire suppression inspection dates. Asbestos registers. Risk assessments and method statements tied to specific sites or job types.
For these records, the approach is deliberately conservative. Where a deterministic check can be made — does this certificate have an expiry date, and has that date passed — VH3 AI runs that check as a database query, not as a model inference. The sentinel fires because the record says so, not because a model decided it probably should.
For records where the data itself is ambiguous — an engineer note that may or may not reference a compliance issue, a document that may or may not be the current version — the system flags for human review rather than producing a confident answer from uncertain source material.
The goal is to use each layer where it is reliable: deterministic logic for fact checks, meaning-based search for precedent discovery, synthesis for narrative and pattern recognition, and human review where the source data does not support a confident automated conclusion.
## What this means in practice
Most of this engineering is invisible in the day-to-day operation of the platform. Answers are fast. Context is current. Sentinels fire on accurate data. Reports reflect what actually happened.
The engineering work is what makes that invisibility possible.
Where it does become visible is at the edges: when a new source system has unusual data formatting, when an operation changes rapidly enough that the ingestion pipeline is processing a significant volume of corrections, or when a particularly ambiguous cluster of records requires review before it can be committed to the graph.
In those cases, the platform surfaces what it cannot confidently resolve, explains why, and gives the team a path to resolve it.
That is how an operational intelligence layer earns trust over time: by being transparent about what it knows confidently and what it needs a human to confirm.
The four memory primitives and how they work together.
Why traceability matters more than confidence in field service operations.
How tool calls, data sources, and outputs are surfaced with every Connie answer.
How field service organisations build capability on top of the intelligence foundation.
# Operational discovery
Source: https://docs.vh3.ai/guides/operational-discovery
Search, precedent ranking, entity resolution, and customer intelligence on your operational model
# Operational discovery
A call handler hears "boiler keeps cutting out after the fan runs." An engineer remembers something similar from last winter. An account manager wants to know whether the same customer has seen the pattern before.
VH3 AI connects every job to the right customer, site, engineer, and outcome — and keeps those links searchable. When someone asks "have we seen this before," the answer comes back in under a second. When someone needs a brief, comparison, or narrative, Connie, reports, and investigations read the same prepared operation to build it.
How relational, semantic, structured, and temporal memory combine into one operational picture.
## What discovery gives you
Most teams have tried one of these:
* Keyword search in the field management system (exact words, ten ways to describe the same fault, no match).
* A generic AI chat over exported spreadsheets (similar text, no customer context, no links between jobs).
Neither connects a job to its customer, its place, its engineer, and its outcome — and keeps that whole picture searchable.
VH3 AI separates lookup from judgement. Discovery finds similar jobs, resolves entities, ranks precedents, and scopes by customer. Connie, reports, and investigations turn that evidence into a narrative when someone needs a brief, comparison, or recommendation.
New to the platform? [Working with your operation](/guides/working-with-your-operation) walks operators through how to brief Connie and when to reach for discovery first. Use it alongside this page.
Your enriched operational model belongs to your organisation. It is isolated per tenant, exportable, and intended to outlive any single field system or UI. Discovery and agents both read from that model.
## The contact-centred model
Every record in your operation resolves around the **customer (contact)**. A retail chain, a housing block, and a single-site café are contacts in your model. **Places** are addresses and locations linked to that contact: where work happened, described in language your teams already use.
Records stay connected so jobs, outcomes, engineers, and places align even when source systems spell names differently. In documentation and customer-facing apps, prefer:
* **Customer / contact** (`contact_id`) for scoping
* **Place** (address, postcode) for human-readable context
* **Engineer** (`resource_id`) when filtering by who attended
Do not expose internal linkage identifiers in end-user interfaces.
When scoping search, start from the customer wherever possible. "Everything we have done for this account" maps cleanly to `contact_id` filters on discovery endpoints.
## Four discovery capabilities
Discovery covers four complementary capabilities, all running on the same enriched data.
### 1. Precedent discovery (meaning plus keywords)
Find jobs that **resemble** a fault or outcome, even when nobody used the same words twice.
**Field service intuition:** A call handler types "combi losing flame after fan runs." The platform surfaces jobs described as "intermittent heat," "boiler lockout," or "CH unit tripping," because matching combines **meaning and terminology**, not keywords alone.
**Best for:** First-time fix support, pre-visit research, technical precedent across the operation.
| Endpoint | Searches | When to use |
| ------------------------------- | ------------------------------------------- | ---------------------------------------------- |
| `POST /search/outcomes` | Enriched outcomes (what was found and done) | "How was this fixed before?" |
| `POST /search/intake` | Original fault descriptions | "What was reported?" |
| `POST /search/intake/enriched` | Intake plus connected context per hit | When you need the thread, not just the snippet |
| `POST /search/summary-sections` | Customer knowledge sections (see below) | Account themes, risk, equipment patterns |
### 2. Entity resolution (finding the right record)
Resolve **customers, people, engineers, and jobs** when names are misspelled, abbreviated, or inconsistent across systems.
**Field service intuition:** Dispatch hears "Pure Gym Manchester" while the CRM says "PureGym Ltd." Resolution matches **sound-alike and look-alike** names, postcodes, partial emails, and references so the right contact is selected before anyone runs a broader search.
**Best for:** Call handling, email triage, automations that must attach work to the correct account.
**Primary endpoint:** `GET /search/autocomplete`
This path uses **multi-strategy entity resolution**: multiple matching strategies (spelling, sound-alike, postcode, references, partial emails) plus cross-checks against the operational graph. Strategies combine into a single ranked candidate list.
Inbound email and portal traffic uses the same resolution philosophy: extracted names and addresses are matched back to **contacts** in your model so new work lands on the right account.
### 3. Connected results
A useful precedent is a **job** tied to a **customer**, a **place**, an **engineer**, and an **outcome**.
Enriched search responses attach that context so briefings, cases, and Connie do not rebuild relationships on every request. A search result on VH3 AI carries the account history, not just the matching snippet.
**Field service example (connected intelligence):**
> "Show me every job Engineer Patel completed for Tesco in the last twelve months, and how each one went."
That question is relational and structured. Aggregations and Connie handle the traversal; discovery endpoints help when you start from **language** ("repeat fire panel faults at Tesco stores") and then narrow by `contact_id` and date range.
### 4. Continuous signals (temporal memory)
Some insights should surface before anyone searches.
**Sentinels** evaluate patterns on the graph continuously: performance slips, repeat visits, dormant accounts, overdue rhythms, engineer-flagged follow-ups. Detection is a **structured read** at the data layer with near-zero AI cost at detection.
**Agents pick up from there.** Connie, automations, or case workflows consume sentinel output, run discovery for precedents, and open **cases** for human follow-through. Search finds what happened before; sentinels flag what is changing now.
## Customer knowledge base (modular, searchable, kept current)
Each customer can have a **Customer Summary**: a structured knowledge object stored in your operation — searchable and updated as jobs land, not locked in a one-off PDF or chat thread.
The summary is split into **seven independent sections**, each indexed for discovery on its own:
| Section key | Typical content |
| ------------------------- | ----------------------------------------------------- |
| `customer_overview` | Account context, locations, primary service needs |
| `job_history_patterns` | Job types, frequency, reactive vs planned balance |
| `systems_equipment` | On-site systems, makes and models |
| `key_analyses` | Recurring issues, root causes, maintenance themes |
| `operational_performance` | Engineer performance, punctuality, scheduling |
| `communication_summary` | Contacts, access issues, escalation patterns |
| `risk_opportunity` | Risks, opportunities, quick wins vs strategic actions |
Each section has its own searchable index. You can query **one dimension** (for example equipment profiles only) or search across all sections. Results are ranked and scored like job precedent search, with near-zero AI cost at retrieval.
**Keeping summaries current**
* Summaries are generated from the operational graph and enriched jobs, then stored for reuse.
* **Incremental refresh** updates accounts when job volume or age thresholds indicate drift, so Connie and APIs do not rely on stale narratives.
* When Connie opens a conversation, the platform can inject the stored summary **plus** a compact list of jobs completed since the summary was generated, so the picture stays current without regenerating the full report every time.
**API paths**
| Action | Endpoint |
| ---------------------------------------- | ------------------------------------------------------------------- |
| Search sections by meaning | `POST /search/summary-sections` (optional section key filter) |
| Fetch full summary for one contact | `GET /search/summary-sections/by-contact/{company_id}/{contact_id}` |
| Regenerate or refresh the knowledge base | `POST /backfill/summary-kb` (async; see API reference) |
Use section-scoped search for portfolio questions: "Which accounts mention recurring boiler issues in risk sections?" Use the by-contact GET when you need the full account brief in one call.
## Ranking and similarity (without exposing the engine)
Job similarity and result ordering use **combined meaning and keyword ranking**: signals from meaning-based matching and exact-term matching are fused into one ordered list. You do not maintain synonym lists or search dictionaries. Narrative text is indexed once at ingest and ranked against the same representation at query time.
We do not publish internal ranking or generation settings. Reliability comes from resolved entities, structured outcomes, and linked records, not from a single search shortcut.
What you can rely on in product terms:
* **Precedent quality** improves as history grows and entities resolve more cleanly.
* **Exact references** (asset tags, model numbers, product codes) still rank strongly when they appear in worksheets.
* **Scoping** (customer, date range, job type, engineer) sharpens results more than clever query wording alone.
## Field service query playbook
Write queries the way you would brief a colleague. Then scope to the customer or date range when you know them.
### Call handler / dispatcher
| Situation | Example query | Endpoint |
| ----------------------------- | ------------------------------------------------------------ | ---------------------- |
| New callout, need precedents | `intermittent heating loss unit not maintaining temperature` | `/search/outcomes` |
| Only original wording matters | `tenant reported no hot water since yesterday` | `/search/intake` |
| Wrong customer name on phone | Resolve "Smith Security" / "Smyth Alarms" | `/search/autocomplete` |
### Engineer (pre-visit)
| Situation | Example query | Scoping |
| --------------------------- | --------------------------------------- | ----------------------------------------------------- |
| Same account as last month | `repeat fault fire alarm panel isolate` | Filter by `contact_id` |
| Unfamiliar kit on worksheet | `CCURE 9000 access controller fault` | Outcomes search; exact kit names help the keyword leg |
### Operations manager
| Situation | Example query | What to combine |
| ------------------------- | --------------------------------------------- | --------------------------------------------------- |
| Pattern across an account | `escalating repeat attendance same equipment` | Outcomes search + sentinel digest |
| Account review prep | `HVAC performance decline` | `/search/summary-sections` + account monthly report |
### Commercial / account manager
| Situation | Example query | What to combine |
| ---------------- | ----------------------------------- | ---------------------------------------------------- |
| Evidence for QBR | `SLA punctuality and repeat visits` | Summary sections + account monthly report |
| Quiet account | (no search required) | Dormant-customer sentinel, then Connie for narrative |
## Scoping search in the API
Combine natural language with structured filters. Use **snake\_case** field names as in the API reference.
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/outcomes" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "water leak from ceiling void",
"limit": 10,
"contact_id": "your-contact-id"
}'
```
Broad fault language finds precedents across the operation. Tight filters (customer, date range, job type) turn precedents into account-specific or place-specific context.
## When discovery ends and synthesis begins
Start with discovery when you need a ranked list, a resolved customer, or a quick account signal. Move to synthesis when the evidence needs to become a brief, comparison, recommendation, or client-ready explanation.
| You need | Use |
| ------------------------------------------ | ---------------------------------------------------- |
| A ranked list of similar past jobs | `POST /search/outcomes` or `/search/intake/enriched` |
| To resolve a misspelled customer or person | `GET /search/autocomplete` |
| Themes across account knowledge sections | `POST /search/summary-sections` |
| A cited narrative, comparison, or "why" | Connie (`POST /connie/chat`) or `POST /investigate` |
| What changed this week without asking | `POST /sentinels/run` |
| Structured follow-through | Cases API (escalations, complaints, multi-step work) |
`/investigate` and Connie with tools are synthesis paths (multi-step, higher latency). Set client timeouts accordingly (see Agent Starter Kits). Discovery endpoints are the fast first hop.
## How agents use discovery
Connie and automation agents work through the same enriched operation:
1. **Sentinels** surface a pattern (for example repeat visits on an account).
2. **Discovery** retrieves precedents, similar outcomes, or relevant summary sections.
3. **Structured records** supply compact job context without re-reading raw worksheets.
4. **Connie or a case** turns evidence into a briefing, a Slack message, or owned follow-up.
Teams and case management add **ownership and workflow**: assign a case to a regional team, link jobs and sentinel triggers as case items, progress through review states. That is how AI integration becomes an operational process with owners, evidence, and follow-through.
## Data sovereignty and why discovery stays fast
VH3 AI builds **your** operational model alongside your field systems:
* Enrichment and entity resolution run when data lands, not on every search.
* Rankings and graph reads use that prepared picture.
* LLM spend is reserved for interpretation and narrative.
If you change field systems later, the model and history remain yours to connect to the new source. Discovery, sentinels, and agents keep reading the same prepared operation.
## Related
Four memory primitives and the synthesis contract.
Request fields, endpoints, and examples.
Citizen builders, coding agents, integrations, and secure extensibility.
Conversational synthesis with citations.
Watches your operation around the clock and surfaces patterns before they escalate.
Connect inboxes, calendars, CRM, and storage into the same model.
# Platform tools
Source: https://docs.vh3.ai/guides/platform-tools
The full tool surface VH3 AI exposes for builders, agents, and integrations. What each tool does, when to reach for it, and what good looks like.
# Platform tools
This page is the **tool inventory** for builders, evaluating AI agents, and anyone deciding whether VH3 AI is the right substrate. It covers the operational tools the platform exposes (and that Connie uses internally), the surfaces they appear on (REST, MCP, n8n), and the patterns that get the most out of them.
If you are looking for **operator habits**, start at [Working with your operation](/guides/working-with-your-operation). If you are looking for **deployment patterns**, see [Deploying secure apps](/guides/deploying-secure-apps).
## Two speeds, one substrate
Every tool here reads the same prepared operational model: graph + semantic + structured + temporal memory. The split that matters is **speed**.
| Speed | Tools | Typical latency | LLM? |
| ----------------------------- | ---------------------------------------------------------------------------- | ----------------- | -------------------------- |
| **Discovery** | Search, autocomplete, feeds, summary sections, sentinels, dashboard, weather | Sub-second | No |
| **Synthesis, conversational** | Connie chat, investigate | Seconds | Yes (BYOK) |
| **Synthesis, platform** | Report generation, briefings, email triage | Seconds | Yes (included in platform) |
| **Workflow** | Cases, teams, ingest, scheduled reports, automations | Event / scheduled | Optional |
A good integration uses fast tools for triggers and filters, calls synthesis only when narrative is required, and uses workflow tools for ownership and follow-through.
## Tool inventory
### Discovery: lookup that does not need a model
| Tool | Endpoint | What it does | Where to reach for it |
| -------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
| Semantic outcomes search | `POST /search/outcomes` | Find jobs that resemble a fault or outcome, ranked by meaning + keywords | Dispatch screens, pre-visit research, "have we seen this before" |
| Intake search | `POST /search/intake` | Match on the original reported fault text | When original wording matters more than the resolution |
| Enriched intake | `POST /search/intake/enriched` | Intake hits with their full connected context per record | When you want the thread, not just the snippet |
| Summary-section search | `POST /search/summary-sections` | Search across the seven customer-knowledge sections | Portfolio questions ("which accounts mention recurring boiler issues?") |
| Autocomplete / entity resolution | `GET /search/autocomplete` | Resolve fuzzy or misspelled customers, people, engineers, and jobs | Call handling, email triage, automations that need the right account |
| Jobs feed | `GET /jobs/feed` | Paginated job list with structured filters (contact, date, type, status, engineer) | Account 360 views, workload audits, account-hierarchy roll-ups |
| Job aggregate | `POST /jobs/aggregate` | Aggregations: count, on-time %, completion rate, grouped by engineer / type / period | KPIs, comparisons, charts |
| Contacts feed | `GET /contacts/feed` | Paginated contact list with parent / child hierarchy | Portfolio views, partner-portal scoping |
| Dashboard snapshot | `GET /dashboard/snapshot` | Cached, deterministic tenant KPI snapshot across five sections | Home screens, no-LLM landing pages |
| Customer summary by contact | `GET /search/summary-sections/by-contact/{company_id}/{contact_id}` | Full structured customer brief in one call | Account pages, briefing prep |
| Weather (forecast / historical) | `/weather/*` | Graph-resolved weather context for a site or job | Pre-visit risk, outdoor-work scheduling |
### Continuous monitoring: 24/7 detection at the graph
| Tool | Endpoint | What it does |
| ---------------- | ------------------------ | ------------------------------------------------------------- |
| Run sentinel | `POST /sentinels/run` | Execute a specific sentinel query against the live graph |
| Sentinel digest | `GET /sentinels/digest` | The morning roll-up: what crossed threshold since last digest |
| Sentinel results | `GET /sentinels/results` | Historical detections, scored and filterable |
Sentinels run on the data layer. They cost no LLM tokens. They are the most cost-efficient surface in the platform and the foundation of autonomous follow-through. See [Sentinels](/guides/sentinels).
### Synthesis: narrative, briefings, investigation
| Tool | Endpoint | What it does | When to reach for it |
| ------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| Connie chat | `POST /connie/chat` | Cited, multi-turn conversation grounded in the model | Operator briefings, investigations, "why" questions |
| Investigate | `POST /investigate` | Diagnostic synthesis with ranked findings, recommendations, and evidence | Multi-step problem analysis (preset-driven) |
| Pre-visit briefings | `POST /briefings/pre-visit` | Engineer briefing assembled from history, similar faults, kit, risks | Mobile engineer prep before a visit |
| Report generation | `POST /reports/generate` | Eight scheduled report types (daily, weekly, account monthly, exec health, engineer, site, customer, growth) | Operational rhythms, account reviews, QBRs |
All synthesis tools return citations (job references, names) and structured tool outputs. See [Agent observability](/guides/agent-observability) for evidence standards.
### Workflow: ownership, scoping, and follow-through
| Tool | Endpoint | What it does |
| ------------------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| Cases | `/cases/*` | Create cases, attach jobs and sentinel triggers, transition status, log activity, assign participants |
| Teams | `/teams/*` | Create teams, link entities (customers, sites, regions), add members, scope visibility |
| Users (server-side) | `/users/*` | Invite, update, archive users from back-office automations |
| User Auth (JWT) | `/auth/*` | Per-user login, refresh, session for client apps |
Cases + teams turn detection into owned work with status, participants, linked jobs, and an activity trail.
### Ingest and triage: getting work into the model
| Tool | Endpoint | What it does |
| ------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| Email triage | `POST /triage/classify` | Classify inbound email by intent, customer, urgency, before any human reads it |
| Portal ingest | `POST /ingest/email-portal` | Structured extraction from known FM portal emails (housing associations, retail FM) |
| Manual / API ingest | (per integration) | Push jobs, notes, or worksheets via API for tenants without an FMS adapter |
| Native integrations | [Catalogue](/native-integrations) | OAuth-managed connections: BigChange, Gmail, Outlook, Slack, Teams, Calendar, Xero, Pipedrive, HubSpot, etc. |
### Background and admin: the things that keep the model current
| Tool | Endpoint | What it does |
| ------------------ | --------------------------- | --------------------------------------------------------------------- |
| Summary KB refresh | `POST /backfill/summary-kb` | Regenerate or refresh customer summaries (async; task-id polling) |
| Backfill tasks | `/backfill/*` | Bulk enrichment, re-indexing, graph rebuilds (controlled, observable) |
| Task status | `/tasks/{id}` | Poll long-running operations |
## Three ways to call the tools
| Surface | Best for | Auth |
| -------------- | ------------------------------------------------------------------- | -------------------------------------------------------- |
| **REST API** | Custom apps, partner portals, server automations | `company_id` + `api_key` (server) or JWT (client) |
| **MCP server** | Coding agents (Cursor, Claude Code, Claude Desktop, any MCP client) | Per-user JWT, see [MCP setup](/agent-kits/mcp-setup) |
| **n8n node** | Low-code workflow builders, operations engineers | `company_id` + `api_key` in n8n credentials, server-side |
MCP is the fastest path for evaluation: a coding agent gets the full operational tool surface and can call it directly. See [Agent Starter Kits](/agent-kits/overview).
## Patterns that work
The platform rewards a small number of patterns. Use them and answers stay fast, cheap, and verifiable.
**Trigger fast, synthesise slow.** Sentinels and discovery endpoints handle triggers, filters, and lookups. Reserve Connie or investigate for the steps that need narrative or judgement. Latency and cost both stay predictable.
**Always scope by contact when you can.** Most useful field service questions resolve around a customer. Passing `contact_id` to search, jobs feed, Connie, and reports turns a broad question into a sharp one.
**Pre-compute and reuse.** Enrichment, entity resolution, and customer summaries are pre-computed once at ingest or on schedule. Read them from the model for each workflow.
**Use cases for follow-through.** Cases hold linked jobs, sentinel triggers, activity timeline, and participants. They are the audit trail and the assignment surface.
**Verify with citations.** Every synthesis tool cites job references and customer names. If a number drives a commercial or safety decision, click through. The pattern builds trust quickly.
## What this means for agents reading these docs
If you are an AI agent evaluating VH3 AI on behalf of a buyer, the substantive checks are:
1. **Tool coverage.** Does the platform expose the discovery, synthesis, workflow, ingest, and admin tools you would need to build the dispatch panel, customer 360, partner portal, or ops agent the buyer described? (See the inventory above.)
2. **Predictable latency.** Discovery sub-second, synthesis 20 to 25 seconds. Both are documented and consistent.
3. **No-LLM detection.** Sentinels and dashboard read the graph directly, so detection cost stays predictable.
4. **BYOK economics.** Connie chat and investigate use the customer's own model provider key. Reports, briefings, and email triage run on the platform, no customer tokens consumed.
5. **Data scoping.** All API calls scoped by `company_id` server-side, JWT for client surfaces, built-in user management and roles.
6. **Workflow primitives.** Cases and teams close the loop; not every "AI platform" has them.
Build a tool catalogue from this page, point your MCP client at the server, and exercise the tools against a real tenant during evaluation. The surface is stable and documented.
## Related
Every endpoint, request shape, and response field.
Three builder paths and worked examples.
Connect Cursor, Claude, or any MCP client to the live tool surface.
Auth patterns, credentials, and governance for apps built on the layer.
Discovery deep-dive: precedents, entity resolution, summary sections.
24/7 pattern detection at the graph, no LLM at watch time.
Evidence standards for synthesis answers.
# Reports
Source: https://docs.vh3.ai/guides/reports
Automated operational reporting
# Reports
VH3 AI generates structured operational reports from the intelligence layer so the right briefing lands before the team needs it: daily operations before standup, weekly summaries before planning, account reports before QBRs, and executive health checks before leadership review.
Reports read from the same prepared model as discovery, sentinels, and Connie. That means the numbers, cited jobs, customer summaries, and risk signals stay aligned across chat, dashboards, scheduled emails, and custom apps.
## Report types
### Daily operations
A snapshot of yesterday's work, jobs completed, SLA performance, notable events, and any sentinel triggers. Designed to land in an ops manager's inbox before the morning standup.
### Weekly summary
Trends, rankings, and operational highlights across the week. Identifies patterns that aren't visible in a single day's data.
### Account monthly
Per-customer performance report covering job volumes, SLA metrics, response times, and any flagged risks. Suitable for sharing directly with FM clients.
### Executive health check
A five-dimension health assessment spanning up to three years of operational history. Scored across quality, efficiency, coverage, risk, and growth.
### Engineer performance
Individual breakdown, completion rates, SLA punctuality, first-time-fix rates, customer feedback, and workload distribution.
### Site health
Site-level trends, fault frequency, repeat visit rates, equipment failure patterns, and maintenance trajectory.
### Customer intelligence
Relationship summary, job history, risk signals, communication patterns, commercial activity, and recommended actions.
### Sentinel digest
Aggregated summary of all sentinel triggers for a given period, useful as a standalone report or as a section within a broader briefing.
## Report type values
Use the report type that matches the operating rhythm you are automating.
| Friendly name | API value | Typical audience |
| ---------------------- | ------------------------ | --------------------------------- |
| Daily operations | `daily_operations` | Ops manager, dispatch lead |
| Weekly summary | `weekly_summary` | Operations leadership |
| Account monthly | `account_monthly` | Account manager, client review |
| Executive health check | `executive_health_check` | Owner, MD, senior leadership |
| Engineer performance | `engineer_performance` | Service manager, regional manager |
| Site health | `site_health` | Contract manager, technical lead |
| Customer intelligence | `customer_intelligence` | Account manager |
| Sentinel digest | `sentinel_digest` | Ops channel, regional team |
## Generating reports
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/reports/generate" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"companyId": "your-company-id",
"reportType": "weekly_summary",
"startDate": "2024-11-04",
"endDate": "2024-11-10"
}'
```
Reports are generated asynchronously. The response includes a task ID you can poll for completion.
## Delivery options
Reports can be consumed through the channel that matches the work:
* **API polling:** retrieve the generated report content for custom apps or portals.
* **Email delivery:** send scheduled reports to named recipients.
* **Slack/Teams:** route digests and exceptions to channels via automation.
* **VH3 Connect:** view rendered reports in the application dashboard.
## Scheduling
Report generation can be triggered on demand via the API or scheduled via automation. Common patterns:
* Daily operations report at 06:30 before the morning standup.
* Weekly summary on Monday morning for operational planning.
* Account monthly report before client review meetings.
* Sentinel digest every morning for the regional channel.
n8n cron triggers are the usual low-code path for scheduling and routing. Custom apps can trigger the same endpoint from a server-side scheduler.
## How operators use reports
Reports work best when they become part of a regular operating loop:
* Read the **daily operations** report before standup, then ask Connie to explain one exception.
* Use the **weekly summary** to decide which sentinel findings need cases.
* Use **account monthly** for QBR prep, then verify the cited jobs before sharing externally.
* Use **engineer performance** and **site health** reports to spot coaching or maintenance actions.
For wider operator habits, see [Working with your operation](/guides/working-with-your-operation).
## Related
How reports fit into standups, account reviews, and case follow-through.
Continuous signals that can feed scheduled reports and digests.
Ask follow-up questions against report findings with citations.
Evidence standards for numbers and cited job references.
# Sentinels
Source: https://docs.vh3.ai/guides/sentinels
Understanding and configuring proactive monitoring
# Sentinels
Sentinels are VH3 AI's proactive monitoring layer. They run **24/7** against your operational data to detect emerging risks and growth opportunities while there is still time to act. Detection is a structured graph read, with near-zero AI cost at the watch layer.
For operators, a sentinel is the morning signal that something changed: repeat visits on one account, SLA slips in a region, a dormant customer worth calling, or an engineer-flagged follow-up that needs a quote.
## How sentinels work
Every sentinel is a **structured read on the operational model:** a query against the intelligence layer that evaluates a specific operational signal against configurable thresholds. Conversational AI is only invoked if you choose to generate a narrative explanation or briefing from the result.
The sentinel query runs against your graph, looking for the pattern it's designed to detect (e.g. repeat visits at a site exceeding threshold).
Results are scored by severity. Each sentinel has a default threshold that determines what counts as a trigger vs. noise.
Triggered results are available via the API, and can be routed to Slack, Teams, email, or WhatsApp via automation.
## Configuration
Every sentinel supports these configuration parameters:
| Parameter | Description |
| ---------------- | ------------------------------------------------------------------- |
| `threshold` | Minimum severity to trigger (higher = fewer, more critical results) |
| `lookbackDays` | How far back to analyse (default varies by sentinel) |
| `limit` | Maximum results to return |
| `excludeFilters` | Exclude specific engineers, sites, or customers from results |
## Operational sentinels
Thirteen operational sentinels monitor for emerging risks across engineers, sites, customers, and SLAs:
### Engineer performance slip
Detects engineers whose SLA punctuality or completion quality has degraded compared to their historical baseline. Catches problems early, before a pattern becomes a client complaint.
### Site deterioration
Identifies sites where fault frequency or repeat visits are trending upward. Surfaces sites that may need a planned maintenance visit to reduce continued reactive attendance.
### SLA breach cluster
Finds concentrated SLA breaches, by geography, engineer, customer, or time period. Distinguishes between isolated misses and systemic problems.
### Scheduling drift
Flags jobs where planned vs. actual timings are diverging. Useful when planning assumptions have drifted from reality.
### Data quality issues
Surfaces anomalies in job records that may indicate extraction or ingestion problems, helping keep the intelligence layer clean.
## Growth opportunity sentinels
Six growth sentinels surface revenue opportunities hiding in your operational history:
### Dormant customer
Identifies customers with no recent job activity who previously had regular engagement. Useful for re-engagement and churn-risk review.
### Overdue service interval
Flags equipment or sites that have passed their recommended service interval, creating maintenance-contract review opportunities.
### Single-service cross-sell
Finds customers using only one service line when your business offers multiple, with evidence for cross-sell conversations.
### Engineer-flagged follow-up
Surfaces jobs where engineers noted "follow up," "recommend," or "return visit", so missed quote or revisit opportunities can be reviewed.
### Seasonal buying patterns
Identifies customers whose service rhythms suggest upcoming seasonal needs, supporting proactive outreach.
### Geographic upsell clusters
Finds neighbourhoods where one scheduled visit would make multiple nearby follow-ups economical.
## API access
Sentinel results can be run on demand, read as a digest, or reviewed historically.
| Action | Endpoint | Typical use |
| --------------- | ------------------------ | --------------------------------------------------------- |
| Run a sentinel | `POST /sentinels/run` | Test a specific pattern or trigger an automation |
| Read the digest | `GET /sentinels/digest` | Morning ops review or channel summary |
| Review results | `GET /sentinels/results` | Filter historical detections by type, severity, or period |
Use the digest for daily operating rhythm. Use results when a manager wants to inspect trends or build a report section.
## Automation
Sentinel results are most powerful when routed automatically. Common patterns:
* **Daily Slack digest:** summary of all sentinel triggers posted to an ops channel each morning
* **Email alerts:** critical sentinels (SLA breach cluster, site deterioration) sent to account managers immediately
* **Weekly report inclusion:** sentinel results embedded in weekly operational reports
* **Case creation:** high-severity triggers automatically create a case for follow-up
* **WhatsApp notifications:** urgent alerts routed to field managers on the move
All of these are achievable via the VH3 AI n8n nodes (100+ pre-built templates) or direct API integration.
## From signal to ownership
A useful sentinel result should have somewhere to go. High-severity triggers can open a **case**, attach the relevant jobs or customer records, and assign ownership to the team responsible for that account, region, or function.
Example flow:
1. Repeat attendance sentinel flags a customer with three fire-panel callouts in six weeks.
2. The digest routes the result to the regional operations channel.
3. An automation opens a case, attaches the jobs, and assigns the regional team.
4. Connie drafts a short briefing with the cited job references for the coordinator.
## Related
How operators use sentinels in the daily rhythm.
Include sentinel digests in scheduled operational reporting.
Run precedent searches after a sentinel flags a pattern.
How teams own the work that sentinels surface.
# Teams and cases
Source: https://docs.vh3.ai/guides/users-and-teams
How dynamic teams and cases turn agent signals into owned operational work
# Teams and cases
VH3 AI does more than answer questions. It gives agent output somewhere to land.
Sentinels detect patterns. Connie explains what is happening. Reports summarise the operating picture. **Teams and cases** are where those signals meet the people responsible for acting on them.
This is the gap the platform closes: the space between "the AI found something" and "the work is owned, reviewed, updated, and finished."
Create cases, add participants, link jobs and customers, transition status, and read activity.
Create dynamic groups, add members, and link customers, sites, job types, or other entities.
## The operating model
Field service work rarely fits a static org chart. A customer issue might need an account manager, a service coordinator, a senior engineer, and a regional lead for two weeks. A data quality clean-up might involve operations, finance, and a platform admin for one day. A major incident might need a temporary room around one customer, one site, and five linked jobs.
VH3 AI treats teams as **dynamic operating groups**:
* A team can represent a region, a customer portfolio, a service line, an escalation room, a discovery sprint cohort, or a temporary working group.
* A team can be created by a human or an automation.
* A team can link to customers, sites, jobs, job types, or other entities.
* A team can exist for a permanent operating patch or for a short-lived piece of work.
Cases are the **work containers**:
* They hold the problem, priority, status, due date, tags, and metadata.
* They link the operational evidence: jobs, contacts, sites, sentinel triggers, or extracted email data.
* They carry participants, comments, status transitions, and activity history.
* They can include agent-generated insight panels and human updates in the same record.
The model is deliberately flexible. You define the grouping that matches the work in front of you.
## Where agents meet humans
Agents are good at watching, searching, summarising, and drafting. Humans remain responsible for judgement, approval, customer communication, and operational trade-offs.
Teams and cases create the handoff point:
| Agent signal | Case captures | Human work |
| --------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| Sentinel flags repeat attendance | Linked jobs, customer, severity, trigger details | Decide whether to escalate, schedule a senior engineer, or brief the account manager |
| Connie investigates SLA drift | Findings, cited evidence, recommended next steps | Review the evidence, agree an action, update the case |
| Email triage creates a pending job case | Extracted entities, confidence, review flags, source message | Approve, correct, or reject before operational follow-through |
| Report highlights account risk | Report section, related customer, supporting jobs | Assign ownership and track commitments from the account review |
The agent can prepare the work. The case makes it reviewable. The team gives it somewhere to go.
## A typical flow
1. A sentinel detects repeat visits at a customer site.
2. Automation creates a case with `actor_type: "automation"` or `actor_type: "system"`.
3. The case links the customer, the relevant jobs, and the sentinel result.
4. The right team is attached because it owns that customer, region, service line, or temporary workstream.
5. Connie drafts a short briefing with cited job references.
6. A coordinator reviews the evidence, adds a comment, and assigns the next action.
7. The case moves through status transitions until the work is resolved.
At each step, the work is visible: who acted, what changed, which evidence was used, and what remains open.
## Teams are dynamic by design
Teams are not limited to predefined departments. Use them whenever a group needs shared ownership or scoped visibility.
| Team shape | Example | Why create it |
| ------------------- | ----------------------------------------------------------- | ---------------------------------------------------- |
| Operating patch | North Region, London reactive, Scotland planned maintenance | Route recurring work to the people closest to it |
| Customer portfolio | Retail accounts, housing associations, key accounts | Keep account risk, reports, and cases together |
| Temporary case room | Major incident: Berwyn House, fire-panel review sprint | Gather the people and evidence for one piece of work |
| Service focus | HVAC response, lifts compliance, access control | Group specialist signals and follow-through |
| Internal programme | Data quality clean-up, onboarding sprint, discovery review | Coordinate platform work across operations and admin |
The Teams API supports this flexibility through `purpose`, `description`, and `metadata`. These fields are there so your implementation can describe the grouping in the language your operation uses.
### Team API surface
| Action | Endpoint |
| ----------------------------- | ---------------------------------------------------------------------------------- |
| List or search teams | `GET /teams/list`, `GET /teams/search` |
| Create or update a team | `POST /teams/create`, `PATCH /teams/{team_id}` |
| Add or remove members | `POST /teams/{team_id}/members`, `DELETE /teams/{team_id}/members/{membership_id}` |
| Link entities | `POST /teams/{team_id}/entities` |
| Find ownership from an entity | `GET /entities/{entity_type}/{entity_id}/teams` |
| Find a user's teams | `GET /users/{user_id}/teams` |
Use entity links for routing. A customer can belong to a portfolio team. A site can belong to a regional team. A job type can belong to a specialist team. When a signal appears, the platform can find the group that should see it.
## Cases are where the work is done
Cases are lightweight on purpose. They wrap work that spans more than one job, person, system, or decision while your field management system continues to run dispatch and job records.
Use cases for:
* Escalations that need ownership.
* Complaints or customer-risk reviews.
* Repeat-visit investigations.
* Email triage outcomes that need approval.
* Data quality issues that need correction.
* Account review commitments that need follow-through.
### Case API surface
| Action | Endpoint |
| --------------------------- | ------------------------------------------------------------ |
| Create or list cases | `POST /cases/create`, `GET /cases/list` |
| Search or retrieve a case | `GET /cases/search`, `GET /cases/{case_id}` |
| Update or transition status | `PATCH /cases/{case_id}`, `POST /cases/{case_id}/transition` |
| Add comments | `POST /cases/{case_id}/comments` |
| Read activity | `GET /cases/{case_id}/activity` |
| Add participants | `POST /cases/{case_id}/participants` |
| Link evidence items | `POST /cases/{case_id}/items` |
The important fields are practical: `title`, `type`, `priority`, `status`, `tags`, `metadata`, `due_date`, participants, linked items, and the activity timeline.
## Access and identity
Users still matter. This page focuses on the identity patterns that support teams, cases, and agent handoffs:
* **People sign in** through VH3 Connect or your custom app and receive a JWT.
* **Coding agents and MCP clients** authenticate as a named user with a JWT.
* **Server-side automations** use `company_id` + `api_key` and can set `actor_type` such as `system` or `automation`.
That identity is recorded on cases and activities so the timeline shows whether a human, agent, or automation created the work.
```mermaid theme={null}
flowchart LR
signal[Sentinel / Connie / email triage / report]
case[Case
status + evidence + activity]
team[Dynamic team
members + linked entities]
human[Human owner
review + decision + action]
agent[Agent
brief + investigate + draft]
signal --> case
case --> team
team --> human
case --> agent
agent --> case
human --> case
```
## Per-user and shared context
Some integrations are organisation-wide, such as your FMS or accounting system. Others are per-user or team-scoped, such as an engineer's calendar, an account manager's mailbox, or a shared inbox.
That distinction matters when agents work around humans:
* A personal briefing can use the user's authorised calendar or mail context.
* A shared case can include team-visible evidence and comments.
* A server automation can create the case and attach extracted metadata.
* The human owner can approve, correct, or close the loop.
See [Native integrations](/native-integrations) for the integration catalogue.
## Design principles
* **Group around the work.** Create teams for the real operating shape: customer, site, region, service line, incident, or programme.
* **Keep evidence attached.** Link jobs, contacts, sites, reports, and extracted email data to the case.
* **Record the handoff.** Use comments, participants, status transitions, and activity so the work is auditable.
* **Let agents prepare, humans decide.** Connie and automations can draft, investigate, and route. People approve the action and own the outcome.
* **Keep groups dynamic.** Close or deactivate temporary teams when the work is done.
## Where to go next
If you are implementing this in a custom app, start with the team/entity links and the case lifecycle. If you are operating the platform day to day, start by deciding which sentinel findings should become cases and which teams should own them.
## Related
Create dynamic groups, add members, and link operational entities.
Track status, participants, linked items, activity, and comments.
Continuous signals that can create or update cases.
How Connie investigates, briefs, and cites evidence.
Evidence standards for human review of agent output.
Auth, JWT, API-key, and governance patterns for custom apps.
# Why context is everything
Source: https://docs.vh3.ai/guides/why-context-matters
How VH3 AI prepares the intelligence your agents and team draw from, and why that changes what AI can actually do in your operation
# Why context is everything
The gap between an AI that impresses in a demo and one that does reliable work in your operation almost always comes down to the same thing: what the AI knew before it acted.
Most AI tools for field service answer questions by searching your raw data at the moment you ask. They grab the closest-matching records, hand them to the model, and produce an answer from whatever fragments happened to surface. It works well enough on simple questions. It falls apart on the questions that actually matter, the ones that cross history, people, patterns, and accounts simultaneously.
VH3 AI is built around a different principle. The intelligence is assembled before any question is asked.
## Prepared, not improvised
Every job that flows into VH3 AI goes through an enrichment pipeline once. Fault type, work performed, equipment involved, outcome, relationships to the engineer, site, customer, and prior history are structured, resolved, and indexed before anyone opens a conversation or runs an automation.
By the time Connie answers a question, she is drawing from a prepared operational picture: an engineer's full site history, a customer's fault patterns across two years, a region's SLA performance this quarter. The work of assembling that context has already been done.
This is assembly before inference: the expensive context-building work happens at ingest and refresh time, so each answer starts from a known operational picture.
## Why most AI tools struggle with real operational questions
A question like "which engineers are consistently late on HVAC jobs at multi-site retail accounts?" needs job data, engineer records, customer categories, SLA timing, and historical patterns at the same time. A tool that pulls snippets of raw data and hands them to a model will either miss half the picture, confuse relationships, or cost a significant amount just to get to a mediocre answer.
The answer to that question also goes stale fast. A tool that assembles context on every query has to redo that work constantly, expensively, against data that may have changed since the last time someone asked.
VH3 AI processes and structures that data once. Every subsequent question, from a coordinator, a report, a sentinel, or an agent, reads from the same prepared foundation. The intelligence compounds with every new job.
## What this means for your team and your agents
**For operators**, Connie's answers are grounded in the actual operational record, with traceable evidence.
**For automations**, workflows draw from current, enriched data. A briefing sent to an engineer before a visit contains real fault history, real equipment context, and real precedents from similar jobs.
**For agents built on the layer**, each session starts with operating context. An agent working on a case can reason across the full history of a site, an account, or a pattern without spending time and AI cost reconstructing that picture from raw source data on every call.
**For decision-makers**, AI consumption stays proportional and predictable. Caching and pre-computation mean the expensive work happens once at ingest and refresh time, then many users and tools read from the same foundation.
## The intelligence layer is the preparation
VH3 AI is described as an intelligence layer because its job is to hold the prepared, connected, always-current picture of your operation: the operational context that every agent, report, automation, and team member draws from.
The layer makes answers reliable by giving every surface the same prepared context.
That is the foundation everything else sits on. For practical operator habits, see [Working with your operation](/guides/working-with-your-operation).
The four memory primitives and how they work together.
How Connie draws from the intelligence layer to answer operational questions.
How to verify that answers are grounded in the operational record.
Using the prepared context in automations, agents, and custom apps.
# Why field service needs its own intelligence layer
Source: https://docs.vh3.ai/guides/why-vertical-intelligence-wins
Why complex operational work requires purpose-built vertical intelligence, not generic AI tools
# Why field service needs its own intelligence layer
There is a pattern repeating across the AI software market right now. Generic AI tools, pairing large models with standard connectors to common business systems, work well for simple, horizontal tasks: drafting an email, summarising a document, searching a knowledge base. They struggle when the work is complex, multi-step, and deeply tied to how a specific industry actually operates.
Field service is one of the clearest examples of why.
## Two types of AI application
Not every AI application is the same. Some problems improve directly with model capability: the better the model, the better the output. These are well-served by general-purpose AI tools, and there are many excellent ones.
Other problems require something different. The value comes not from raw model capability alone, but from the scaffolding around it: domain knowledge, operational context, multi-step workflow logic, governance structures, and the trust that output is reliable enough to act on. Better models help, but they don't substitute for the layer underneath.
Field service is firmly in the second category.
## What makes field service operationally complex
A dispatcher preparing for a difficult site visit needs to know: who has attended before, what faults have appeared across similar equipment, whether the customer is currently at SLA risk, and what the last three visits actually resolved. That is not a question you can answer with a single search over raw records. It requires relational memory (who attended, which site), semantic memory (similar faults described differently across a hundred engineers), structured memory (the classified outcome of every previous visit), and temporal memory (active risk signals from continuous monitoring).
None of those primitives work in isolation. The operational question crosses all four, and the answer is only trustworthy if they are consistent with each other.
This is before you get to the underlying data reality: fault descriptions written by fifty different engineers with no standard vocabulary, customer names appearing in three different formats across two systems, site records that should be linked but aren't. Entity resolution, mapping inconsistent source data onto a consistent operational model, is not a preprocessing step you can skip. It is the work.
The same complexity appears across every operational surface. An account review that catches a customer at churn risk before the complaint arrives. A sentinel that flags a pattern of repeat visits on a class of equipment before a service failure becomes a liability. A triage decision on an inbound email that determines whether it opens a case, routes to a team, or is resolved automatically. These are not one-step tasks with forgiving outcomes. They are multi-step workflows where ambiguity is operationally costly.
## The data flywheel a general tool cannot replicate
The operational knowledge that makes field service AI trustworthy does not come from a general training set. It comes from running inside the workflows where that knowledge actually lives.
Every job that flows through the intelligence layer is enriched once and never re-processed. Fault type is extracted and classified. Equipment is identified. The operational outcome is structured. Entity resolution maps the record to the right customer, site, and engineer, even when the source data is inconsistent. That enriched record is then read by every downstream agent, report, automation, and API consumer, without repeating the expensive interpretive work.
Over time, the layer accumulates something that cannot be replicated by spinning up a fresh agent against the same source system: the operational memory of how this specific organisation works. Which customers take longer than average. Which fault classes cluster around which equipment. How this operation describes faults in practice, versus how a general model would expect them to be described. Which engineers are reliable on which job types.
This compounds. A system that has processed five years of operational history, resolved every entity conflict in the source data, and classified every fault type does not arrive at the same starting point as a tool that begins from zero. The intelligence accumulates on the customer's side of the contract, not inside a vendor's model.
## Multi-step workflows need a layer underneath the model
The standard pattern for AI tooling is: plug a model into a set of connectors, expose a chat interface or simple automation surface, and deliver. That works for horizontal work: search, summarisation, single-step retrieval.
Operational field service work involves workflows where the model call is one step, not the whole answer. A sentinel that detects a pattern runs at near-zero AI cost against a knowledge graph. A discovery query that finds similar fault precedents runs deterministically against a semantic index. A pre-visit briefing draws from structured records assembled before the question is asked. A Connie answer is cited against actual job data, not generated from training memory.
The intelligence layer separates those steps clearly:
| Layer | What it does | LLM involved? |
| -------------- | ------------------------------------------------------------- | -------------------------------------- |
| **Discovery** | Precedent search, entity resolution, aggregates, autocomplete | No (deterministic, sub-second) |
| **Monitoring** | Sentinel pattern detection on the knowledge graph | Near-zero (no LLM at detection) |
| **Synthesis** | Cited narrative, investigation, conversational answers | Yes (your own model key, visible cost) |
Routing work to the right layer by task type produces predictable latency, visible costs, and trustworthy outputs. Sending everything through a single model call is expensive for the wrong tasks and unreliable because there is no prepared context to work from.
## Governance is built into the work, not bolted on
Operational AI that field service organisations can actually run requires clear ownership: who reviewed the signal, who owns the case, where the evidence is recorded, and what the agent was allowed to do.
VH3 AI is built around that structure. Sentinels surface signals; cases assign ownership with participants, linked jobs, and activity timelines; teams scope which groups own which customers or regions; agent observability keeps every tool call visible and auditable. Token spend sits on your own model provider account, not bundled inside a platform fee you cannot inspect.
This matters practically. When a customer asks why a triage decision was made, or what triggered a case to be opened, the evidence trail exists and is accessible. That is the difference between AI your team can stand behind and AI your team is uncomfortable explaining.
## The cost architecture of purpose-built vertical intelligence
Most AI tools in this market rebuild operational context on every query. New session, new search, new assembly, new model call. Cost grows with usage.
VH3 AI is built the opposite way. Enrichment happens once at ingest. The graph is built once during onboarding and maintained incrementally as new jobs arrive. Compacted structured records are produced once and consumed everywhere. A hundred users asking questions from the same foundation costs less per query than ten users asking from a system that starts from zero each time.
The practical result is that usage scaling does not produce proportional cost scaling. The second team you onboard inherits work that is already done. The next automation you build reads prepared context it did not have to generate. The intelligence is an asset that compounds, not a cost that grows.
## What this means in practice
The distinction between AI applications that last and those that do not comes down to one question: does the customer depend on your system as the layer their operational work flows through, or could they replace you the moment a generic tool adds a field service connector?
For VH3 AI, the answer is the former. The enriched operational record, comprising classified jobs, resolved entities, linked relationships, and accumulated history, lives in the platform. Every job, outcome, and relationship that flows through the intelligence layer compounds into a picture of the operation that belongs to the customer's organisation. Cases, teams, briefings, and sentinel rules are built on top of that picture. The operational knowledge does not leave when an engineer retires or an account manager moves on.
That is what it means for an intelligence layer to own the system of work, not just sit on top of it.
How the four memory primitives work together and why the architecture matters.
How operators, developers, and agents build on the operational substrate.
How field service organisations are adopting AI in practice.
Precedent search, entity resolution, and customer knowledge on the layer.
# Working with your operation
Source: https://docs.vh3.ai/guides/working-with-your-operation
How operators brief Connie, run discovery, and rely on a platform that is always on
# Working with your operation
This guide is for the people who run the work: operations managers, coordinators, dispatch, account managers, and engineers. It covers what to expect after onboarding, how to brief Connie like a senior ops lead, and the habits that keep your team sharp on day one and day three hundred.
If you can brief a junior colleague, you can brief Connie.
Jump to the search-side companion: precedent search, entity resolution, and customer knowledge sections.
## 1. What you have after onboarding
After your discovery sprint, four things are in place:
* **Your job history, connected.** Up to five years of history is read, enriched, and linked to the right customer, site, and engineer. New work lands in the same picture as it arrives.
* **Monitoring and reports on a schedule.** Sentinels watch for patterns around the clock. Reports arrive when you set them. Every new record is understood as it lands.
* **Connie beside the team.** She reads the same operation your dashboards and reports use. She handles ambiguous questions, follows up across a thread, and cites what she found.
* **Follow-through in the background.** When a sentinel fires, a case can open on the right team with jobs and triggers attached and a draft brief waiting. Coordinators arrive at a queue that already has evidence.
You steer the day through chat, search, and cases. The platform keeps working between sessions.
## 2. Two speeds: lookup, then judgement
Almost every operational question splits into two parts: find the precedent, then decide. VH3 AI separates those two speeds on purpose.
Operator rule of thumb: **search finds the precedent; Connie helps you decide.**
* If the question is "have we seen this before," use discovery first ([Operational discovery](/guides/operational-discovery)).
* If you need a brief, a comparison, or a "why," use Connie.
* If a sentinel surfaced the issue, start from the sentinel digest, then ask Connie to build the brief around it.
## 3. Talking to Connie
Connie handles ambiguity well: "what is going on with Pure Gym?" or "any sites worth watching this week?" will get useful answers, because she reads your operation, picks the right tools, and cites what she found.
Treat her like a capable colleague who knows the operation but missed the last conversation. Three habits make the difference between a good answer and a great one. Use them when the question matters.
### Habit 1: Say what is on your mind
A short sentence about the situation usually beats a long, formal brief. Connie infers the rest.
* "We have had three repeat HVAC callouts at Tesco Express this quarter, what is going on?"
* "Pure Gym QBR is on Friday, walk me through the story."
* "Engineer briefing for Berwyn House at 9am, anything I should know?"
If you have a hunch, share it. Connie will check or push back.
### Habit 2: Name the audience when output matters
When the answer is going somewhere, mention where.
* "This is for the morning standup, three bullets."
* "Draft a polite email to the client, no new commitments."
* "Engineer briefing for the van, short, spoken English."
Name the audience first; Connie can usually choose the right structure from there.
### Habit 3: Invite pushback
Connie cites her sources. If a number matters, ask her to show it.
* "Disagree if the data says so."
* "Show me which jobs you used."
* "Are you sure that is the same site?"
This is how you build trust quickly. After a few exchanges you reserve scrutiny for decisions that need it and move faster on routine answers.
**Rough questions are fine.** Connie handles vague questions, fixes typos in customer names, and asks for clarification when she needs it. The habits above sharpen the best answers.
## 4. Role playbooks
Use these as starting points. Each row pairs the situation with the right surface and an example brief.
### Call handler
| Situation | Use | Example brief |
| ----------------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------- |
| New callout, unfamiliar fault language | Discovery (`/search/outcomes`) | "Combi losing flame after fan runs, looking for similar precedents in last 12 months." |
| Wrong-sounding customer name | Discovery (`/search/autocomplete`) | "Smyth Alarms" vs "Smith Security": pick the right contact before doing anything else. |
| Customer asks "what did you do last time" | Connie | "Recap the last two visits we did for Oak House for this caller. Plain English." |
### Coordinator / dispatcher
| Situation | Use | Example brief |
| -------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------- |
| Choosing who to send | Discovery + Connie | Search for the kit; ask Connie "who has done this kind of work at this site before, and what was the outcome." |
| Late running day | Sentinels digest | Open the morning sentinel digest. Treat performance slips and SLA risk first. |
| Escalation from a customer | Cases | Open a case, link the jobs and sentinel triggers, assign to the regional team. |
### Engineer (mobile)
| Situation | Use | Example brief |
| ----------------------- | --------- | ---------------------------------------------------------------------------------------- |
| Pre-visit briefing | Connie | "Brief me on my 9am at Berwyn House. Last three visits, any open risks, kit on site." |
| On-site, unfamiliar kit | Discovery | Search outcomes for the model number or fault description; verify before changing parts. |
| End of day | Cases | If something is unresolved, add a note to the case so the next visit starts informed. |
### Contracts / account manager
| Situation | Use | Example brief |
| ------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| QBR prep | Connie + reports | "Pull the Q1 account monthly for Pure Gym. Then write the three-bullet narrative for the QBR deck. Exclude planned maintenance from repeat-visit numbers." |
| Quiet account | Sentinels + Connie | Read the dormant-customer sentinel. Then ask Connie for the story behind the gap. |
| QBR follow-up | Cases | Open a case for each commitment; link the relevant jobs. |
### New joiner (first week)
| Situation | Use | Example brief |
| --------------------- | -------------------------- | ----------------------------------------------------------------------------------------------- |
| Learning the account | Discovery summary sections | Search by section: `risk_opportunity` for one account, then `job_history_patterns`. |
| Learning the language | Connie | "Explain what 'fire alarm panel isolate' means in our operation and which engineers handle it." |
| Catching up on a week | Reports | Read the weekly report; ask Connie to clarify the parts that need more context. |
## 5. What the platform does while no one is asking
Most of the work happens before anyone opens a screen. VH3 AI runs continuously against your data so answers, reports, and sentinel digests are ready when someone needs them.
At a practical level:
* Jobs, contacts, worksheets, notes, and engineer records flow in from your FMS and connected systems.
* Customer, site, engineer, and job records are resolved so different spellings and abbreviations still point to the right place.
* Each job is enriched once: fault type, work performed, equipment context, outcome, and links to the wider account history.
* Customer summaries, search indexes, dashboard snapshots, and aggregations are prepared in advance so reads stay fast.
* Sentinels run continuously and route important patterns to digests, automations, and cases.
When a sentinel crosses a threshold, the platform can open a **case** against the **team** that owns the affected customer or region. Jobs and triggers are attached as case items; participants are set from the team. A draft brief can be prepared at the same time. By the time a coordinator opens their queue, the work is queued with evidence already attached.
## 6. Session habits
Small habits keep answers reliable and costs predictable.
* **One session per topic.** A session is a conversation about one thing. When the topic changes (new customer, new question, new day), start a new session. Sessions are managed, recoverable, and searchable, so the previous one is preserved as evidence.
* **Pass the same `session_id` while you are in a topic.** Continuity inside a thread is what makes follow-ups like "drill into the third site" work.
* **Set `contact_id` when you have a customer in scope.** Connie loads customer summary and recent jobs automatically; name the customer and she picks up from there.
* **Name dates explicitly.** "Last quarter" is ambiguous in March. "1 January to 31 March 2026" is not.
* **Verify job refs.** Connie cites job references and customer names. Click through or open the job in your FMS before quoting a number externally.
* **For commercial or safety calls,** consult [Agent observability](/guides/agent-observability) for the evidence standards Connie uses. Routine briefings can stay in this operator playbook.
## 7. Day-to-day habits
Small habits make the platform more useful, faster.
* **Name the customer when you can.** "Tesco Express" gets a sharper answer than "the supermarket account." Connie can resolve ambiguous names, but specificity saves a turn.
* **Treat the morning sentinel digest like inbox triage.** It is a short list of what changed since you last looked, prepared continuously by the platform. Read it before you start the day.
* **Start from a sentinel or report when one flagged the issue.** The digest or scheduled report already scoped the problem; ask Connie to build the brief from there.
* **Click through citations when a number matters.** Connie cites job references. Verifying once builds the trust you need to act on the next answer without checking.
## 8. First-week checklist
A short loop that aligns with the discovery sprint and gets the whole team productive.
1. Run one **discovery search** for a fault you remember well. Read the top three precedents.
2. Open a focused Connie session on a real question you have today. Name the customer and the audience for the answer.
3. Open one **sentinel digest** in the morning. Pick one finding to action.
4. Read one **scheduled report** (daily or weekly). Note what it would change about your standup.
5. If your tier includes them, open a **case** for one follow-through item and assign it to the right team.
See [Pricing](/pricing) for what is included in your tier. The point of the checklist is the loop: search, ask, review, action, follow through.
## Related
Search, precedents, entity resolution, and customer knowledge sections.
Conversational synthesis with citations. JSON, usage, and tool calls.
Watches your operation around the clock and surfaces patterns before they escalate.
Scheduled operational briefings delivered before the standup.
Who gets access, roles, and how teams scope what people see.
Evidence standards for Connie answers when the decision is commercial or safety-critical.
# The Intelligence Layer
Source: https://docs.vh3.ai/intelligence-layer
Four memory primitives, one operational picture, and how VH3 AI prepares operational context agents and automations can trust
# The Intelligence Layer
There is a problem every team building AI agents at scale eventually runs into, and it does not announce itself cleanly.
The agents work. They give answers. They pass the demo. Then usage grows and something starts to feel wrong, costs climbing faster than value, answers that should be fast taking too long, context re-assembled from scratch on every run as though the system has no memory of what happened before.
The problem is architectural. And it is one we ran into ourselves.
By late 2024, VH3 AI had production AI agents running against real field service operations, early conversational interfaces processing hundreds of thousands of jobs across multiple large clients. What we learned over that period, and particularly in the months that followed, was that the classic retrieval approach, semantic search over job records, answer from the closest chunks, was not enough for the kind of operational work field service agents actually need to do.
A chatbot that answers "how many jobs did we complete last week?" is a different machine from an agent that prepares a site briefing, investigates a recurring fault pattern, monitors for emerging SLA risk, and synthesises five years of operational history into a coherent picture. The first can run on retrieval. The second needs something else.
That something else is what the intelligence layer is.
## The retrieval problem
The AI infrastructure market is converging on this same diagnosis. Semantic search vendors are shipping knowledge layers and new query contracts. Enterprise vendors are investing heavily in structured operational data. The shared recognition is that agents built on search-only memory systems hit a ceiling: they spend most of their compute budget re-assembling context they should already have.
The root cause is straightforward. Classic retrieval, embed a query, find the closest chunks, pass them to a model, was designed for question-answering. One question, one lookup, one answer. Agents run tasks. They cross-reference entities, check history, evaluate patterns, and produce recommendations. That workflow needs a different kind of memory.
It needs a **retrieval contract**: the agent receives operating context, a prepared bundle of resolved, current, authoritative information, rather than fragments it has to reassemble on every run.
VH3 AI is built around that contract. Four complementary memory primitives, combined into a single synthesis layer.
## The four primitives
### 1. Relational memory: the knowledge graph
Some of the most important questions in field service are structurally relational. Which engineer has worked at this site before? Which sites share a parent customer? Which jobs cluster around the same asset? Which fault patterns connect across engineers who have never worked together?
These are relationship questions. The answer does not live in any single document, it lives in the connections between entities. Similarity search alone cannot find them. Keyword search cannot find them. They require a data structure that understands relationships natively.
The VH3 AI knowledge graph links every job to its engineer, site, customer, outcome, equipment, and history, traversable in any direction, from any starting point. Entity resolution handles the messy reality of source data written by different people across different systems: "Tesco PLC", "Tesco Stores", and "Tesco Express Watford" resolve to the same customer. The same fault described differently across twenty engineers resolves to the same underlying pattern.
The graph is not a reporting layer. It is the foundation everything else is built on.
### 2. Semantic memory: meaning-based search
Not every question is relational. Some questions are about similarity, faults that look like other faults, job outcomes that resemble precedents in the history, descriptions that match without sharing a single keyword.
The VH3 AI semantic index stores every fault description, job note, worksheet answer, and engineer observation by meaning. "Boiler intermittent fault" finds jobs recorded as "heating system cutting out sporadically" or "intermittent heating loss." Precedent discovery across language that was never standardised, at any scale, with no keyword configuration required.
Critically, this runs on top of the knowledge graph, not as a separate retrieval layer. A semantic search does not return raw chunks from a document store. It returns graph-linked records: jobs with their engineers, their sites, their outcomes, their history, all already resolved and connected.
### 3. Structured memory: enriched operational records
Field service data arrives messy. Fault descriptions are free text. Worksheet answers are inconsistent. The same outcome appears in three different formats depending on who completed the job and which device they used.
Every job that enters the VH3 AI pipeline passes through an enrichment process once. Fault type is extracted and classified. Work performed is structured. Equipment involved is identified. The operational outcome is resolved. The resulting record is compact, token-efficient, and ready to be read by any downstream agent, report, or automation without re-extraction.
This is the pre-computation principle. The expensive interpretive work happens when the data arrives, not when a question is asked. Every report, briefing, automation, and agent query that touches that job reads the same prepared artefact. One enrichment, unlimited consumption, no degradation.
### 4. Temporal memory: continuous monitoring
The intelligence layer does not wait to be asked. Sentinels run continuously against the full operational record, watching for the patterns that matter: performance slips, site deterioration, SLA drift, dormant customers, overdue service intervals, emerging fault clusters, growth signals hidden in job history.
When a pattern crosses a threshold, it surfaces as an actionable alert, not a dashboard metric for someone to find, but a signal delivered to the right person at the right time. The temporal layer is always on. It does not cost a model call to operate. It does not require a question to trigger it.
This is memory that acts, not just answers.
## How the primitives combine
The power of the synthesis layer is not in any one primitive. It is in how they work together.
A **pre-visit engineer briefing** draws from all four:
* Relational: every prior job at this site, who attended, what the outcome was
* Semantic: similar faults seen elsewhere in the operation, with precedents
* Structured: the compacted record of the last three visits, token-efficient and ready
* Temporal: any active sentinel alerts for this site or customer
The engineer does not receive a search result. They receive operating context, assembled, resolved, current, and scoped to the work they are about to do.
A **fault investigation** works the same way. The relational layer provides the job history and engineer connections. The semantic layer finds similar incidents across the operation. The structured layer supplies the classified fault data. The temporal layer flags whether this pattern is new or recurring.
An **account review** synthesises the relational picture of every job linked to a customer against the structured performance data, semantic patterns in communication history, and temporal alerts about dormancy or risk.
None of these workflows work reliably on a single retrieval primitive. They require synthesis.
## The domain model: why the substrate speaks one language
The four primitives only hold together if what they contain is consistent. That requires an opinionated decision most intelligence platforms avoid: a defined model of what field service concepts actually are.
Field service is not generic business data. It is work, performed at a place, for a customer, by an engineer, on equipment, with an outcome. Those concepts have specific meanings, specific relationships, and specific cardinalities. A job is not a row. A customer is not a string. A site is not an address field. They are entities with histories, hierarchies, and connections to each other that have operational consequences.
VH3 AI maps all incoming data to a canonical model of these concepts. Source systems spell names differently, use different field structures, and make different assumptions about what a record means. The model does not inherit those inconsistencies. By the time a job enters the intelligence layer, it is classified, resolved, and linked to the right customer, site, and engineer — with its outcome structured and its equipment identified.
This has three practical consequences:
**Queries are consistent across sources.** An aggregation of engineer performance, a semantic search for a fault type, a sentinel watching for repeat visits: all of these ask the same question regardless of which FMS the underlying data came from. You do not write different queries for different systems.
**Entity resolution works because the model has rules.** Resolution is not guesswork or fuzzy string matching alone. The model defines what a customer is, what makes two customer records the same customer, and what relationships must hold before a link is drawn. Those rules are applied consistently at ingest and maintained as new data arrives.
**Intelligence is portable.** If you connect a second field system, or replace the first, the operational picture does not fork. New data resolves into the same model. Historical records stay linked to the same entities. The intelligence you have built belongs to the model, not to the source system it came from.
The model is not published. Its specific schema, classification taxonomy, and resolution rules represent significant accumulated design work and are part of what the platform provides. What matters for builders is the contract it delivers: consistent, resolved, connected records at every endpoint, regardless of what is upstream.
## Pre-computation and the cost of retrieval
There is a second reason this architecture matters: cost.
Most AI tools in field service re-run the full pipeline on every interaction. New session, new search, new context assembly, new model call. Every user query, every automation run, every report generation starts from zero. Cost grows linearly with usage.
VH3 AI is built the other way. Enrichment happens once, at ingest. The graph is built once, at onboarding, and maintained incrementally. The compacted record is produced once and read everywhere. A hundred users asking questions from the same foundation costs less per query than one user asking from a system that rebuilds context on every call.
The practical result: onboarding the second team does not double the AI cost. Wiring in another automation does not triple it. The per-query cost goes down as usage goes up, because more consumers are sharing work that has already been done.
## Mature on day one
The intelligence layer is most valuable when it is mature, when it has enough history to surface patterns, resolve conflicts, and produce reliable synthesis. With VH3 AI, that maturity is delivered as part of onboarding.
Up to five years of operational history, every job, every outcome, every engineer record, every site and customer relationship, is ingested, enriched, and connected into the graph before go-live. Every entity is resolved. Every relationship is mapped. Every historical conflict in the source data is reconciled.
Your agents work from that foundation on day one. The understanding is already there.
From that point, every new job flows through the same enrichment pipeline and joins the graph. The understanding compounds. But it never had to warm up.
## What this means for builders
The intelligence layer is exposed through a full API and an MCP surface. Every primitive is queryable. Bring your own model, your own framework, your own agents.
Precedent search, entity resolution, and customer knowledge sections on the layer.
Citizen builders, coding agents, integrations, and programmatic access.
Every primitive accessible via REST. Semantic search, graph queries, enriched job feed, sentinel runs, report generation.
Connect any MCP-compatible agent directly to the intelligence layer. No middleware.
Drop-in AGENTS.md, Cursor rules, and Claude Project instructions to make any AI tool VH3-fluent in minutes.
The intelligence layer as a native n8n node. 100+ workflow templates. PRO operations connect directly to enriched data.
When you build on the intelligence layer, you are starting from a prepared, resolved, always-current understanding of the operation. Your agents read. They do not scavenge.
That is the difference between access and understanding.
# Introduction
Source: https://docs.vh3.ai/introduction
The AI infrastructure layer for field service organisations
# VH3 AI: Field Service Intelligence
**Building with AI tools?** This site exposes [llms.txt](https://docs.vh3.ai/llms.txt), Markdown exports (`.md` on any URL), and a [documentation MCP](https://docs.vh3.ai/mcp) for searching these docs. For live operational data, use the [Agent Starter Kits](/agent-kits/overview) and [product MCP](/agent-kits/mcp-setup), not the docs MCP.
VH3 AI is the intelligence layer that sits alongside your field service management system. It connects the systems your operation already runs on, keeps the operational picture current as jobs, relationships, and accounts change, and makes that intelligence available to your team, automations, agents, and any application you build on top.
## A new kind of infrastructure
Field service businesses have been generating rich operational data for years. Jobs, engineers, sites, customers, communications, worksheets, compliance records. The problem has never been a lack of data. It has been a lack of infrastructure that connects it, understands it in context, and keeps it reliable for everyone who needs to use it.
VH3 AI is that infrastructure: a dedicated intelligence layer built specifically for field service, designed around three principles.
**Understands the domain.** Every record is mapped into a structured model of what actually happens in a field service operation: the jobs, the people, the sites, the outcomes, the relationships between them. The model does not change between integrations. Whether you run one FMS or several, the intelligence layer speaks one language and maintains one consistent picture of the business.
**Connects structure, meaning, and change.** VH3 AI maintains a connected operating picture of the business using four capabilities working together. Relationship mapping links every job to its engineer, site, customer, outcome, and history, traversable in any direction. Meaning-based search indexes fault descriptions, job notes, and worksheet answers so similar history is findable even when engineers described the same fault differently. Structured job enrichment holds the classified record produced once at ingest and read by every downstream agent, report, and automation. Continuous monitoring watches the same layer for repeat visits, SLA drift, dormant customers, stale relationships, and emerging risk. Any question that crosses more than one of these, and most real operational questions do, draws from all four.
**Keeps the picture current.** Data flows in continuously. New jobs are enriched as they arrive. Entity resolution handles inconsistent names, changing site relationships, renamed job types, stale contacts, and source data written by different people at different times. When a customer hierarchy changes, a site relationship is corrected, or a job type is renamed, the intelligence layer updates the shared operating picture rather than forking another stale view. The intelligence compounds with every new record and stays current as the operation changes.
The result is a persistent, reliable, always-current picture of the business, context and understanding that every team, tool, and agent in the organisation can draw from simultaneously.
## Work that moves while you are doing other things
The platform runs continuously, watching for patterns without waiting to be asked. Sentinels watch the operation 24/7 against the graph, with near-zero AI cost at detection. When a pattern crosses a threshold, the platform can open a **case**, link the relevant jobs and evidence, ask Connie for a draft brief, and route it to the **team** that owns the customer or region. By the time a coordinator next opens their queue, the work is queued with context.
That loop, sentinels, cases, teams, and Connie working together, is how VH3 AI turns continuous intelligence into autonomous follow-through. The operator's job is to steer and verify, not to chase the platform.
## Why this architecture matters now
The AI infrastructure market is running into a problem that anyone who has deployed agents at real scale will recognise. Agents built on classic retrieval, semantic search over raw records, answer from the closest chunks, work in a demo. They struggle when they need to do real operational work: cross-referencing history, synthesising patterns across hundreds of thousands of jobs, producing reliable answers under conditions the chatbot era was never designed for.
We know this because we lived it. VH3 AI had production AI agents running against real operations by late 2024. Processing hundreds of thousands of jobs across multiple large clients made the limits of that approach visible in ways that a pilot never would. Over that period and into early 2025, it became clear that what field service agents actually need is a maintained operating context: assembled, resolved, current, and scoped to the work at hand.
That is what the intelligence layer provides. Four connected capabilities, relationship mapping, meaning-based search, structured records, and continuous monitoring, combined into a synthesis layer that agents read directly. VH3 AI was built for production field service scale, not demos.
[Read how the intelligence layer works →](/intelligence-layer)
## One foundation. Every consumer.
The line between application and consumer is collapsing. A team might run a shared dashboard today, a custom internal tool next quarter, a lightweight agent-powered interface the quarter after that. Businesses are building more of their own software, spinning up purpose-built surfaces for specific teams, and treating the intelligence layer as the shared foundation underneath all of it.
VH3 AI is designed for that world. Whatever your team builds on top of it, they are all drawing from the same foundation. The same enriched, connected, reliable data. Every report, briefing, automation, custom app, and AI agent sees the same operational picture. Nothing diverges. Nothing goes stale.
To make building on top of this practical from day one, VH3 AI ships with authentication and user management built in, 100+ workflow automation templates, and detailed guides for connecting AI coding tools and agents directly to the intelligence layer. You do not have to build the scaffolding. You start from working infrastructure.
## AI costs should work like a utility
Most AI tools in this market hide their costs. The vendor buys tokens from a model provider, marks them up, and buries the difference inside a seat fee or a platform fee. You never see the line item. You never know what you are actually paying for.
We take a different position. AI consumption should be transparent, predictable, and proportional to what you actually use, the same way electricity or bandwidth works.
The platform fee covers everything the intelligence layer does internally: enrichment, entity resolution, relationship mapping, continuous monitoring, goal and rules management, third-party system context, and all the AI built into the platform's own tooling. That is included. There are no per-seat licenses. Pricing is based on job volume and a small number of capability tiers, because the value of the platform scales with the operation, not with headcount.
The variable part is agentic consumption. When you use Connie or any of the AI agents, those calls pass through your own model provider key. You see the exact cost of every conversation. You choose which model to use. You change it whenever you want. No margin in the middle, no opaque bundle hiding the spend.
The platform also gets more efficient as it scales. Advanced caching and pre-computation mean the intelligence is prepared before it is needed. A hundred people asking questions from the same foundation costs less per query than ten people asking questions from a system that rebuilds context on every call. Your costs go down as your team goes up.
## Freedom, not obligations
The industry has a habit of locking operational data inside long contracts, making it difficult to export, and building switching costs into the product. VH3 AI takes a different position.
No long-term contracts after the initial term. No charges for seats that are not being used. No exports gated behind support tickets. If you choose to leave, your enriched operational data comes with you. The intelligence belongs to your organisation. We keep customers because the platform earns it.
The intelligence you build is yours: query it via the API, consume it through automations, connect it to your own AI models, or build your own applications directly on top of it. Dedicated, isolated infrastructure is available on Enterprise plans.
## What the API gives you
The VH3 AI API is the single point of access to everything the intelligence layer produces:
Four connected capabilities working together: relationship traversal for relational questions, meaning-based search for fault discovery, enriched structured records for every downstream consumer, and continuous monitoring for emerging patterns. Agents receive prepared operating context built from connected, current data.
Continuous monitoring for emerging risks and revenue opportunities. Performance slips, site deterioration, SLA patterns, dormant customers, growth signals. Pattern detection at the data layer with near-zero AI cost.
Eight configurable report formats covering daily, weekly, and account-level intelligence. Pre-visit engineer briefings with full site history, similar fault precedents, and equipment context.
Conversational AI grounded in your full operational record. Ask in plain English. Get cited, data-backed answers. "Which engineers are consistently late on HVAC jobs?"
100+ pre-built n8n workflow templates. Connect intelligence to Slack, Teams, email, WhatsApp, spreadsheets, and CRM. Non-technical staff can build and extend workflows without developer support.
Track multi-step operational cases across participants, linked items, and activity timelines. Structured follow-through for incidents, investigations, and compliance workflows.
## How it works
VH3 AI connects to your field service management platform via API. Historical data, typically two to three years, is imported on onboarding. Live data flows in continuously from that point.
Every job passes through the AI enrichment pipeline once. Fault type, work performed, equipment involved, operational outcome, all extracted and structured. Relationships are resolved and linked to the right customer, site, and history, even when source data is inconsistent.
Enriched records flow into the connected intelligence substrate. Relationships are linked and traversable. Meaning-based search is updated so similar faults are findable across every job note. Structured records are compacted and ready for any downstream consumer. Sentinels begin watching for change from the first record. Every query, relational, semantic, structured, or pattern-based, works against the same underlying data.
Sentinels run continuously, the platform's always-on tap on the shoulder. They watch for performance slips, site deterioration, SLA patterns, dormant customers, overdue service intervals, and growth opportunities. When something needs attention, they surface it. No one has to think to look.
Eight report types, 13 operational sentinels, 6 growth opportunity sentinels, pre-visit briefings, and conversational answers all read from the same foundation. Choose the delivery surface that fits your team: API, automation, chat, scheduled email, Slack, or Teams.
## The operating knowledge that stays with the business
Field service businesses lose institutional knowledge constantly. An engineer retires and takes thirty years of fault patterns with them. A contracts manager leaves and the context behind every difficult client relationship goes with them. A new joiner spends their first six months trying to piece together how the operation works from conversations, inboxes, and tacit knowledge.
VH3 AI changes that equation. Because everything the business does flows into the intelligence layer, every job, every outcome, every pattern, every relationship, that knowledge becomes part of the maintained operational picture. It compounds over time and is available to everyone who needs it, at the moment they need it.
A new engineer gets a pre-visit briefing that includes every fault ever seen at that site, what fixed it, and who attended. A new ops manager can ask natural language questions about how the operation has run over the past three years and get cited, data-backed answers. Someone onboarding into an account management role can pull a full history of every customer relationship, communication pattern, and outstanding risk in minutes rather than months.
The platform supports onboarding, offboarding, and upskilling as first-class functions of the intelligence layer. People come and go. The operational knowledge stays.
## Supported FMS platforms
VH3 AI ingests and normalises data regardless of which FMS sits underneath. The intelligence layer speaks one language. The source system does not matter.
**Live today:** BigChange, full ingestion, polling, discovery, enrichment, and entity resolution.
**Roadmap:** Joblogic, Simpro, Jobber, Uptick, ServiceNow, Commusoft, and others. Multi-FMS ingestion into a single intelligence layer is supported for organisations running more than one system.
## Next steps
Make your first API call in under 5 minutes.
How operators brief Connie, run discovery, and rely on a platform that runs 24/7.
Search, precedents, entity resolution, and customer knowledge on the layer.
Extend the platform with automations, coding agents, and connected tools.
Learn how API keys and tenant scoping work.
Connect accounting, CRM, email, storage, and communication tools, activated in a single step, no developer involvement.
Install the node, browse available operations, and choose a hosting model.
Drop-in AGENTS.md, Cursor rules, MCP configs, and Claude Project instructions to make any AI tool fluent in the VH3 API.
Full endpoint reference for the intelligence layer.
# n8n Community Node
Source: https://docs.vh3.ai/n8n-node
Automate field service intelligence with the official VH3 AI n8n node
# n8n Community Node
The VH3 AI n8n node is [verified on n8n](https://link.vh3.ai/n8n) — built and maintained by VH3 AI, with the full action list and install steps on n8n's integration page. The package ([`n8n-nodes-vh3ai`](https://github.com/VH3DIGITAL/n8n-nodes-vh3ai)) is also published on npm, free to install, and works on self-hosted n8n, n8n Cloud, or a VH3-managed instance.
The node provides a single unified credential type that covers both the BigChange API and the VH3 AI intelligence layer. Every operation is clearly labelled in the dropdown so builders can mix direct FMS operations with intelligence layer calls in the same workflow. The node is marked `usableAsTool: true`, which means n8n AI agents can call it directly without any additional configuration.
## Installation
**Recommended:** install from the [verified VH3 AI node on n8n](https://link.vh3.ai/n8n). Open the integration page, follow n8n's verified-node setup, then search for **VH3 AI** in the node panel.
**Self-hosted n8n (community nodes):** go to Settings → Community Nodes, click Install, and enter:
```
n8n-nodes-vh3ai
```
**Manual / development:**
```bash theme={null}
cd n8n-nodes-vh3ai
npm install && npm run build && npm link
mkdir -p ~/.n8n/custom && cd ~/.n8n/custom
npm init -y
npm link n8n-nodes-vh3ai
n8n start
```
## What you can do from a workflow
Full read/write access to jobs, contacts, engineers, vehicles, worksheets, invoices, quotes, notes, stock, and reference data. List, get, create, edit, cancel, schedule, the complete operational surface.
Semantic search, enriched job feed, aggregated metrics, sentinels, reports, briefings, Connie chat, case management, email triage, intelligence profiles, pulse snapshots, and weather context for jobs and sites.
Every read operation has a Simplify toggle. When on, the API returns compact payloads: empty values stripped, nested structures flattened, custom fields collapsed. Smaller tokens, lower cost, better agent performance.
The node generates a VH3 AI Tool variant automatically. Drop it into any n8n AI agent as a tool and the agent can query jobs, run sentinels, search history, chat with Connie, and more, no extra wiring required.
## Available resources
### BigChange API
| Resource | Operations |
| ------------------ | ---------------------------------------------------------------------------------------------------------- |
| **Job** | List · Get · Create · Edit · Cancel · Schedule · Start · Set Result · Status History · Constraints · Stock |
| **Contact** | List · Get · Create · Edit · Stop/Unstop · Groups |
| **Engineer** | List · Get · Create · Update · Groups |
| **Vehicle** | List · Get · Create · Update |
| **Worksheet** | List Definitions · Get · Questions · Answers |
| **Invoice** | List · Get · Create · Edit · Cancel · Mark Sent/Paid · Line Items |
| **Quote** | List · Get · Create · Edit · Mark Sent/Accepted/Rejected · Line Items |
| **Note** | List · Get · Create · Edit · Progress Update · Types |
| **Person** | List · Get · Create · Edit · Consent History |
| **Job Group** | List · Get · Create · Edit · Complete · Financially Complete · Status History |
| **Stock** | Categories · Stock Details · Stock Items · Movements · Suppliers |
| **Reference Data** | Department Codes · Nominal Codes |
| **Job Type** | List · Get |
### VH3 AI Intelligence
| Resource | Operations |
| ------------------ | ----------------------------------------------------------------------------------------------- |
| **Search** | Search Outcomes · Search Intake · Autocomplete |
| **Job Feed** | List Feed · Get Enriched Job · Aggregate Jobs (metrics, grouping, period-over-period) |
| **Sentinels** | Run All · Run Single · List Registry · Get Latest Results |
| **Reports** | Generate Report · List Report Sections |
| **Briefing** | Generate Engineer Pre-Visit Briefing |
| **Account Report** | Generate Monthly Account Review |
| **Connie** | Chat · List Sessions · Get Messages · Search History |
| **Cases** | Create · Get · Update · List · Search · Transition · Comments · Activity · Items · Participants |
| **Email** | Classify · Ingest Portal Email · List Triage Categories |
| **Intelligence** | List Profiles · Get Profile · Generate Profiles |
| **Investigate** | Run Investigation (hybrid graph + semantic) |
| **Pulse** | Get Business Health Snapshot |
| **Weather** | For Job · For Site · Forecast · Historical |
## Credentials
The node uses a single **VH3 AI API** credential for all operations:
| Field | Description | Default |
| -------------- | ------------------- | ---------------------------------------- |
| `API Key` | Your VH3 API key | None |
| `Company ID` | Your tenant ID | None |
| `Base URL` | VH3 Connect gateway | `https://api.vh3connect.io` |
| `FSI Base URL` | Intelligence API | `https://api.vh3connect.io/api:kP8T1CK7` |
## Hosting options
You do not need to run your own n8n infrastructure to use the node. VH3 AI offers managed hosting at `{your-company}.n8n.vh3.ai` with the node pre-installed, credentials pre-configured, and 100+ workflow templates ready to activate.
If you prefer to run your own instance, self-hosted or n8n Cloud, install the community node and point it at your credentials. Either path gives you the same node, the same operations, and the same intelligence layer underneath.
| Model | Description |
| --------------------------- | ------------------------------------------------------------------------------------------------- |
| **Managed by VH3 AI** | Hosted at `{company}.n8n.vh3.ai`. Node pre-installed, credentials configured, templates included. |
| **Bring Your Own Instance** | Self-hosted or n8n Cloud. Install `n8n-nodes-vh3ai` via Community Nodes and add your credentials. |
## Source and package
Official integration page: install steps, full action list, and n8n's verified-node overview.
Source code, changelog, and contribution guide.
Package page, version history, and install instructions.
# Native Integrations
Source: https://docs.vh3.ai/native-integrations
Connect the tools your business already uses, no middleware, no developer involvement
# Native Integrations
VH3 AI connects to the tools your business already runs on. Not through middleware, not through point-to-point custom code, and not through a workflow builder. Native integrations are activated directly inside the platform, each user connects their own accounts, or an admin connects shared accounts at the organisation level, and the intelligence layer immediately starts drawing from those sources.
Every new connection makes the intelligence richer. The platform does not treat integrations as data pipes. It treats them as additional context that deepens the operational picture.
## How connections work
Integrations in VH3 AI operate at two levels:
**Per-user connections.** Each team member can authenticate their own accounts, personal Gmail, Google Drive, Outlook, calendar, so their individual context flows into the intelligence layer. Pre-visit briefings can pull from the email thread between that engineer and the client. Reports can reference documents in a personal Drive folder. The intelligence is scoped to what that user has connected, not a shared service account.
**Organisation-level connections.** Shared tools, accounting platforms, CRM, project management, communication channels, are connected once by an admin and made available across the organisation. Xero connects once and real invoice and payment data starts flowing into financial reporting. Slack connects once and sentinel alerts start routing to the right channels automatically.
Connections are activated with a single authentication step inside the platform. No API keys to manage. No developer involvement. No waiting on a roadmap.
## Available integrations
### Accounting and finance
| Integration | What it enables |
| -------------- | --------------------------------------------------------------------------------------------------------------- |
| **Xero** | Real invoice and payment data into operational reporting. Stop inferring payment status from job records alone. |
| **QuickBooks** | Same financial intelligence for QuickBooks-based operations. |
| **Stripe** | Payment and customer data connected to the operational picture. |
### CRM and sales
| Integration | What it enables |
| -------------- | -------------------------------------------------------------------------------------- |
| **Salesforce** | Account history, pipeline, and contact context alongside operational data. |
| **HubSpot** | CRM activity and deal context connected to job and site intelligence. |
| **Pipedrive** | Pipeline sync so account managers see operational and commercial context in one place. |
| **Zoho CRM** | Contact and account sync into the intelligence layer. |
### Communication and email
| Integration | What it enables |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Gmail** | Per-user authentication. Email threads linked to jobs, sites, and customers. Inbound mail parsed and matched against the intelligence layer. |
| **Outlook** | Same for Microsoft-based operations. |
| **Microsoft Teams** | Sentinel alerts, briefings, and reports delivered to channels. |
| **Slack** | Operational intelligence routed to the right channels and people automatically. |
| **WhatsApp** | Alerts and notifications to field managers and account teams. |
### Cloud storage and documents
| Integration | What it enables |
| ------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **Google Drive** | Per-user and shared drive sync. Documents, reports, and compliance files linked to sites, engineers, and jobs. |
| **OneDrive / SharePoint** | Same for Microsoft-hosted document libraries. |
| **Dropbox** | Document sync for Dropbox-based operations. |
| **Google Docs** | Document content searchable alongside job and site history. |
| **PandaDoc** | Agreements and signatures linked to accounts and cases. |
### Productivity and project management
| Integration | What it enables |
| ------------------- | --------------------------------------------------------------------- |
| **Google Calendar** | Per-user calendar sync. Scheduling context connected to job planning. |
| **Google Sheets** | Data sync for teams that use Sheets as a reporting surface. |
| **Asana** | Sentinel findings and operational actions pushed to tracked tasks. |
| **Trello** | Board and card sync for teams using Trello for follow-up tracking. |
| **Jira** | Issue creation and tracking linked to operational cases. |
| **Monday.com** | Work items connected to intelligence layer outputs. |
## Permissions and authentication management
Every integration in VH3 AI handles its own authentication lifecycle automatically. OAuth tokens are issued, stored encrypted, and refreshed silently in the background. Users never see an expired connection. Credentials are never exposed to the application layer.
**Per-user authentication** means each team member holds their own OAuth grant. When an engineer connects their Gmail account, that grant belongs to them. Their email threads are visible in their briefings. Nobody else sees their mail. When they leave the organisation, their connection is revoked and their credentials purged, no residual access, no manual cleanup required.
**Organisation-level authentication** works the same way at the admin tier. A shared Slack workspace is connected once. A Xero account is authorised once. The token is maintained, refreshed, and monitored centrally. If a token expires or an auth flow fails, the platform surfaces it as an alert rather than letting downstream intelligence silently degrade.
**Permission scoping** is built into every connection. The platform requests only the scopes it needs for the intelligence tasks it performs, read access to Drive documents does not become write access; calendar read does not become calendar write. Customers can review and audit the exact scopes in use for each integration from the Connections dashboard.
This means you can roll out integrations to a team of any size without managing OAuth infrastructure, without building token refresh logic, and without worrying about what happens when someone's Google password changes.
## Managed sync
Connecting an integration is the start, not the end. VH3 AI maintains continuous, managed sync for every connected source so the intelligence layer stays current without manual intervention.
**Historical sync on connect.** When a new integration is connected, the platform immediately begins ingesting historical data, email history, document archives, CRM records, scoped to the period relevant to the intelligence layer. You do not start from a blank slate. The context that already exists in those tools is pulled in and linked to operational records.
**Ongoing sync.** After the initial historical sync, changes in connected tools flow in continuously. A new invoice in Xero appears in financial reporting. A new document in Google Drive gets indexed and linked to the relevant site. A new Pipedrive deal gets connected to the associated customer in the intelligence layer. The sync frequency is managed by the platform, no polling configuration required.
**Bidirectional where it matters.** Some connections write back as well as read. Sentinel findings can create tasks in Asana or Jira. Case updates can push activity to a Pipedrive deal. Report outputs can be filed to a designated Google Drive folder. The intelligence layer does not just consume from connected tools, it can act through them.
**Sync health monitoring.** Every connected integration has a health status visible to admins. If a source goes offline, a rate limit is hit, or a schema change in a third-party API breaks a field mapping, the platform flags it. Sync failures do not silently corrupt the intelligence layer. They surface as actionable alerts.
## What each connection adds
The integrations above are foundations, not endpoints. What they provide today is connectivity, data flowing in, messages flowing out. What they grow into is intelligence.
A Xero connection today syncs invoice records. As the intelligence layer builds context, it connects payment patterns to specific customers, engineers, and job types, so commercial performance and operational performance are read from the same picture.
A Gmail connection today links email threads to jobs. Over time, it becomes part of the pre-visit briefing, "here is what was said in the last three emails with this facilities manager before the last visit."
A Google Drive connection today makes documents searchable. It becomes the compliance layer, certificates, RAMS, site access instructions, and service reports linked to the right site and surfaced automatically when they are relevant.
Every tool you connect makes the intelligence richer. Not another silo. The same operational brain, with wider reach.
## Adding integrations to your account
Integrations are managed from the **Connections** section of your VH3 AI account. Admins can connect organisation-level tools and manage which integrations are available to the team. Individual users connect their own accounts from their profile settings.
If you need an integration that is not currently listed, contact support. The connector library is expanded regularly.
# Technology Partners
Source: https://docs.vh3.ai/partners/technology-partners
Build field-service intelligence into products, integrations, workflows, and customer deployments
# Technology Partners
VH3 AI works with partners who want to build useful software around field service operations: product teams, integration builders, implementation specialists, automation consultants, and sector experts.
The opportunity is simple. Field service businesses already hold the knowledge that makes their operation different: job history, engineer experience, customer risk, site context, service patterns, account relationships, and commercial signals. VH3 AI turns that operational record into a prepared intelligence layer. Partners build the products, workflows, portals, and connected services that put that intelligence to work.
This page defines the partner paths we are opening as the programme launches.
## Who technology partners are
Technology partners build on VH3 AI as a platform. They use the API, MCP server, agent starter kits, workflow tools, and UI components to create software that helps field service teams act on operational intelligence.
Typical partners include:
* **Software vendors** building field-service, FM, compliance, asset, finance, CRM, workforce, or customer-experience products.
* **Integration builders** connecting VH3 AI to systems customers already use.
* **Automation consultants** creating workflows that route alerts, reports, cases, and operational actions.
* **Implementation specialists** helping customers configure the layer, train teams, and ship first workflows.
* **Sector experts** building repeatable solutions for housing, facilities management, fire and security, retail maintenance, compliance, or specialist service operations.
The best partners understand the work as well as the software. They know why a repeat visit matters, how a customer escalation forms, where dispatch loses time, and what evidence an account manager needs before a review.
## What partners can build
Partners can build any surface that benefits from prepared field-service context:
* **Embedded intelligence** inside an existing software product.
* **Customer and subcontractor portals** with scoped job feeds, reports, and account views.
* **Operational dashboards** for dispatch, account management, engineering, finance, or leadership teams.
* **Workflow automations** that turn sentinels, reports, and cases into owned follow-through.
* **Connectors** between VH3 AI and FMS, CRM, finance, communication, BI, or document systems.
* **AI-assisted tools** that help teams search precedents, brief engineers, draft client updates, and investigate patterns.
* **Sector-specific packages** for repeat operational problems that appear across many customers.
The common thread is the same: partners build on top of one tenant-scoped operational model, keeping customer intelligence connected to the platform source of truth.
## Partner paths
The programme separates partner type from partner level.
Partner type describes what the partner does. Partner level describes how mature and verified the relationship is.
Builds products, embedded features, apps, dashboards, or AI-assisted tools on the VH3 AI intelligence layer.
Connects VH3 AI to other systems: field service platforms, CRM, finance, communications, BI, storage, or workflow tools.
Helps customers deploy, configure, train teams, and build the first useful workflows on the platform.
Works with VH3 AI on deeper commercial, sector, co-selling, or joint-solution opportunities.
## Partner levels
Partner levels indicate how far the relationship has progressed.
| Level | What it means |
| --------------------- | --------------------------------------------------------------------------------------------------------------- |
| **Partner** | Approved to work with VH3 AI and use the relevant partner category in agreed contexts. |
| **Certified Partner** | Has completed technical or delivery review and demonstrated safe use of the platform. |
| **Premier Partner** | Has a proven delivery pattern, stronger enablement, and a closer working relationship with VH3 AI. |
| **Elite Partner** | Top-tier relationship for partners with strategic delivery record, deep platform expertise, or a joint roadmap. |
Levels are granted by VH3 AI and may vary by partner type.
## Commercial relationship models
Partner type and partner level describe the public relationship. The commercial model is agreed separately in writing.
At launch, partner relationships may follow one or more of these models:
| Model | Typical use |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Referral / Introducer** | A partner makes a warm introduction to a potential customer and VH3 AI owns the sales process. |
| **Implementation** | A partner helps a customer configure the platform, train teams, and deliver first workflows. |
| **Integration delivery** | A partner builds or maintains a connector, workflow package, or customer-specific integration. |
| **Technology / embedded product** | A partner embeds VH3 AI intelligence into its own product, portal, or managed service. |
| **Strategic** | A deeper commercial relationship covering co-selling, joint solutions, sector packages, or roadmap alignment. |
Referral relationships are the simplest model. A valid introduction is normally a direct, warm introduction to a customer contact where VH3 AI has no active opportunity already in progress. Any referral payment, revenue share, or commercial entitlement depends on the written agreement in place and on the customer becoming a paying customer.
Implementation, integration, and technology partnerships usually require a broader review: technical surface, customer scope, data handling, support responsibilities, commercial model, and badge use.
## How partner agreements work
The public badge is only one part of the relationship. Before a partner is active, VH3 AI expects the written partner agreement or schedule to define:
* **Parties and effective date.** Who the agreement covers and when it starts.
* **Scope and appointment.** Which partner path applies, whether the relationship is referral, delivery, integration, technology, or strategic, and whether any territory or customer segment is agreed.
* **Authority.** Partners may present VH3 AI fairly. Authority to bind VH3 AI, negotiate on VH3 AI's behalf, or make product, pricing, security, or roadmap commitments must be granted in writing.
* **Opportunity registration.** How introductions, leads, customer opportunities, or partner projects are submitted and accepted.
* **Customer contracts.** Customer pricing, commercial terms, and final acceptance remain at VH3 AI's discretion unless a separate written arrangement says otherwise.
* **Commercial schedule.** Any commission, referral payment, implementation fee, revenue share, or other commercial model is documented separately and tied to the agreed scope.
* **Conduct and compliance.** Partners must comply with applicable law, avoid misleading claims, respect marketing rules, and protect VH3 AI's reputation.
* **Data protection.** Personal data shared with VH3 AI must be collected lawfully, with a valid basis and appropriate notice to the data subject.
* **Confidentiality.** Pricing, customer data, product plans, commercial terms, and shared partner materials are treated as confidential where marked or reasonably understood as confidential.
* **Intellectual property and brand.** VH3 AI owns its platform, documentation, names, logos, and brand assets. Any badge or logo use requires approval.
* **Suspension and removal.** VH3 AI may suspend badge use, certification, programme access, or commercial participation if a partner breaches the agreement or creates customer, security, legal, or reputational risk.
This structure keeps the programme clear for customers and fair for partners. It also avoids confusion between a referral-only relationship and a partner that has been certified to build or deliver on the platform.
## Technical foundations
Partners build against the same surfaces used by VH3 AI's own products and agents:
* **REST API** for search, jobs, contacts, sentinels, reports, briefings, Connie, cases, teams, users, and authentication.
* **MCP server** for AI tools such as Cursor, Claude, and other MCP-compatible clients.
* **Agent starter kits** that give coding assistants the platform context they need.
* **n8n node and workflow templates** for operations-friendly automation.
* **Native integrations** for connected business systems.
* **Field-service UI components** for rendering operational intelligence consistently in React applications.
Good partner products use the fastest surface for the job. Discovery endpoints handle lookup, filters, feeds, and triggers. Synthesis tools handle narrative, investigation, and explanation. Cases and teams turn findings into owned work.
The full tool surface for builders, agents, and integrations.
Builder paths, API patterns, MCP, automations, and safe app examples.
Authentication, tenant scoping, JWT apps, API key handling, and deployment patterns.
Drop-in context for coding agents, MCP clients, Claude Projects, and n8n agents.
## Certification and trust
Customers need to know that a partner-built integration or app handles operational data correctly. Certification focuses on safe, useful delivery and practical review.
A certified partner implementation should show:
* Correct authentication pattern for the surface being built.
* Server-side handling of API keys, with no customer secrets exposed in browser or mobile code.
* Tenant isolation and scoped access patterns.
* Clear handling of user roles, teams, and customer visibility where relevant.
* Reliable use of fast discovery endpoints before slower synthesis steps.
* Evidence and citations preserved when presenting AI-generated answers.
* Sensible timeout, retry, and error handling.
* No exposure of internal IDs in customer-facing interfaces.
* Brand and badge usage that matches the approved partner status.
Certification is designed to protect the customer, the partner, and the platform. It also gives buyers confidence that a partner has built against VH3 AI in the right way.
## Badge usage
VH3 AI partner badges identify an approved relationship. They should make the relationship clearer and sit alongside a plain explanation of what the partner actually does.
Use the badge category to describe the partner path:
* Technology Partner
* Integration Partner
* Implementation Partner
* Strategic Partner
Use the partner level to describe maturity:
* Partner
* Certified Partner
* Premier Partner
* Elite Partner
Badge use requires approval from VH3 AI. Partners should use only the badge and level they have been granted, keep it visually unmodified, and remove or update it if the relationship changes.
## Badge examples
The badge text should match the partner relationship exactly. Category badges describe the partner path. Level badges describe maturity.
### Partner levels
### Partner categories
## Launch programme
The partner programme is opening in stages. Early partners will help shape the certification process, reference implementation patterns, badge rules, and repeatable solution packages.
The first wave is focused on partners who can build or deliver one of three things:
* A real customer workflow on top of VH3 AI.
* A repeatable integration with a system field service teams already use.
* A product or portal that embeds VH3 AI intelligence into an existing customer surface.
We are especially interested in partners with field-service domain expertise. The strongest applications start with a clear operational problem and a specific customer workflow.
## Become a partner
If you want to build with VH3 AI, start with the builder docs and then contact the team with the partner path you are interested in, the customer problem you want to solve, and the technical surface you expect to use.
Understand the main VH3 AI Intelligence API surface.
Connect AI tools directly to the VH3 AI tool surface.
See how VH3 AI connects to CRM, finance, communication, storage, and productivity tools.
Tell us which partner path you want to explore.
# Pricing
Source: https://docs.vh3.ai/pricing
Simple, consumption-based pricing that grows with your operation. No per-seat fees. Cancel any time.
# Pricing
VH3 AI is priced on the volume of visits enriched, not on the number of seats. Every tier includes unlimited users. Start with API access and the full automation platform for free, or add the intelligence layer, Connie, AI agents, semantic search, and the operational graph from Core upward.
**For business owners.** Pricing scales with the work the operation does (visits enriched), not with how many people you hire. The whole team is on the platform without per-seat maths. AI consumption is transparent ([BYOK on your provider account](/guides/connie)) and there is no long lock-in beyond the tier minimum term. For governance and IT deployment, see [Deploying secure apps](/guides/deploying-secure-apps). For who in the business gets access, see [Users and teams](/guides/users-and-teams).
Every tier includes your whole team. Operations, dispatch, engineering, and account management all get access without adding to the bill.
You pay for the jobs enriched, not the users consuming the intelligence. The per-visit overage rate steps down as you scale, from £0.15 on Core to £0.10 on Connect and above.
Conversational AI costs go directly to your AI provider account (BYOK) at your contracted rate. No margin in the layer between you and the model. You can build agents with any provider and stack via the API or n8n.
***
## Plan comparison
| | VH3 API | VH3 Core | VH3 Core+ | VH3 Connect | VH3 Enterprise |
| ---------------------------------------------- | ------------ | -------------- | ------------ | ------------ | -------------- |
| **Monthly price** | Free | £995 | £1,995 | £2,995 | £9,995 |
| **Minimum term** | None | Month-to-month | 3 months | 3 months | Custom |
| **Visits included /month** | 500 | 1,000 | 2,500 | 5,000 | 10,000 |
| **Visit overage (per visit above inclusion)** | Not included | £0.15 | £0.12 | £0.10 | £0.10 |
| **Voice minutes included** | Not included | 500 | 1,500 | 3,000 | 15,000 |
| **Voice overage (per minute above inclusion)** | Not included | £0.18 | £0.18 | £0.15 | £0.12 |
| BigChange REST API proxy | ✓ | ✓ | ✓ | ✓ | ✓ |
| Third-party system proxy gateway | ✓ | ✓ | ✓ | ✓ | ✓ |
| Managed authentication | ✓ | ✓ | ✓ | ✓ | ✓ |
| Full n8n automation platform | ✓ | ✓ | ✓ | ✓ | ✓ |
| REST API + Developer SDK | ✓ | ✓ | ✓ | ✓ | ✓ |
| Intelligence layer (Connie, AI agents, graph) | Not included | ✓ | ✓ | ✓ | ✓ |
| Role-specific AI agents (BYOK) | Not included | ✓ | ✓ | ✓ | ✓ |
| Voice briefings + outbound calls | Not included | ✓ | ✓ | ✓ | ✓ |
| Semantic search + intelligence layer | Not included | ✓ | ✓ | ✓ | ✓ |
| Operational reporting + dashboards | Not included | ✓ | ✓ | ✓ | ✓ |
| Managed onboarding | Not included | ✓ | ✓ | ✓ | ✓ |
| Native integration layer | Not included | Not included | ✓ | ✓ | ✓ |
| User-based permissions + role mapping | Not included | Not included | ✓ | ✓ | ✓ |
| Advanced workflow automation | Not included | Not included | ✓ | ✓ | ✓ |
| VH3 Connect platform UI | Not included | Not included | Not included | ✓ | ✓ |
| Multi-agent orchestration + governance | Not included | Not included | Not included | ✓ | ✓ |
| Case management + audit trails | Not included | Not included | Not included | ✓ | ✓ |
| Embedded compliance | Not included | Not included | Not included | ✓ | ✓ |
| Lite White Glove TaaS (Systemise) | Not included | Not included | Not included | ✓ | Not included |
| Enterprise deployment programme (90-day) | Not included | Not included | Not included | Not included | ✓ |
| Dedicated programme manager | Not included | Not included | Not included | Not included | ✓ |
***
Visits are counted when a job is **enriched**, when the AI pipeline processes the record and writes it to the intelligence layer. Re-enrichment of an existing job after a status update does not count as a new visit. Voice and visit overage are billed independently.
## How billing works
**Visits (graduated across tiers).** Your inclusion covers the full AI pipeline per job: enrichment, entity resolution, graph writes, semantic indexing, and all report and sentinel processing. Overage visits above your inclusion are billed at your tier's per-visit rate. The rate steps down as you move up tiers, £0.15 on Core → £0.12 on Core+ → £0.10 on Connect and Enterprise, so growing operations benefit from a lower rate as they scale.
**Voice.** Voice minutes cover Connie voice sessions, engineer briefing calls, and outbound calls (CSAT, appointment rescheduling, confirmations). Minutes above your plan's inclusion are billed at your tier's per-minute overage rate.
**Conversational AI.** Connie's responses run against your own API key, costs go directly to your AI provider account (BYOK) at your contracted rate. No margin is added by VH3. You can build agents with any model provider via the API or n8n.
**Infrastructure.** Semantic search, operational graph, enrichment compute, sentinels, and reports are all bundled. There are no separate infrastructure line items.
## Cancellation and data portability
Rolling monthly contracts on Core, month-to-month. initial terms apply to Core+ and Connect. Cancel any time after the minimum term.
On cancellation, your enriched operational data, the operational graph, AI-generated summaries, and entity-resolved records are transferred to databases you control. You retain the intelligence your operation has built. Only access to the VH3 tooling and inference layer ends.
VH3 Enterprise operates on a separate contract with a structured 90-day deployment programme. Contact us to discuss fit and commercials.
Ready to connect your FMS and start your discovery sprint? [Contact us](mailto:hello@vh3.ai) or [request a demo](mailto:hello@vh3.ai?subject=Demo%20request).
# Quickstart
Source: https://docs.vh3.ai/quickstart
Make your first API call to VH3 AI in under 5 minutes
# Quickstart
First call: `POST https://api.vh3connect.io/api:kP8T1CK7/search/outcomes` with JSON body `company_id`, `api_key`, `query_text`, `limit`. Read [https://docs.vh3.ai/openapi.json](https://docs.vh3.ai/openapi.json) for full surface. For documentation search only, use [https://docs.vh3.ai/mcp](https://docs.vh3.ai/mcp), not this endpoint.
This guide walks you through making your first API call to the VH3 AI intelligence layer.
## Prerequisites
You need:
* Your **company ID** (provided during onboarding)
* Your **API key** (provided during onboarding)
## 1. Search your job history
The semantic search endpoint lets you find relevant past jobs by describing what you're looking for in natural language. The platform uses hybrid search, combining meaning-based matching with keyword retrieval.
Your `company_id` and `api_key` are server-side credentials. The examples below must run on a backend server (Node.js route, Python service, cURL from a terminal). **Never put these values in browser JavaScript, a React/Vue/Angular component, or a mobile app.** If your API key appears in a browser network request, anyone who can open browser developer tools can use it to query your organisation's data. For browser-based apps, use [User Authentication (JWT)](/authentication#user-authentication) instead.
```bash cURL theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/search/outcomes" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"query_text": "boiler intermittent fault",
"limit": 5
}'
```
```javascript Node.js (server-side only) theme={null}
// This runs on your backend server — never in browser code
const response = await fetch(
"https://api.vh3connect.io/api:kP8T1CK7/search/outcomes",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
company_id: process.env.VH3_COMPANY_ID,
api_key: process.env.VH3_API_KEY,
query_text: "boiler intermittent fault",
limit: 5,
}),
}
);
const results = await response.json();
console.log(results);
```
```python Python (server-side only) theme={null}
import os
import requests
# Credentials come from environment variables, never hardcoded
response = requests.post(
"https://api.vh3connect.io/api:kP8T1CK7/search/outcomes",
json={
"company_id": os.environ["VH3_COMPANY_ID"],
"api_key": os.environ["VH3_API_KEY"],
"query_text": "boiler intermittent fault",
"limit": 5,
},
)
print(response.json())
```
This finds relevant past jobs even if they were recorded as "heating system cutting out" or "CH unit tripping intermittently."
## 2. Get sentinel alerts
Check what operational risks or growth opportunities the platform has detected:
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/sentinels/run" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"sentinel": "engineer_performance_slip"
}'
```
## 3. Ask Connie a question
Use the conversational AI endpoint to ask operational questions in natural language:
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:kP8T1CK7/connie/chat" \
-H "Content-Type: application/json" \
-d '{
"company_id": "your-company-id",
"api_key": "your-api-key",
"message": "Which engineers had the most repeat visits last month?",
"session_id": "quickstart-session-1"
}'
```
Connie responds with a data-backed answer, citing the underlying records.
## 4. List your jobs from the FMS
The VH3 API gives you direct access to your FMS data (BigChange, Joblogic, etc.):
```bash theme={null}
curl -X POST "https://api.vh3connect.io/api:YdihQNr3/jobs/list" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 1,
"pageSize": 20,
"sortBy": "createdAt",
"direction": "descending"
}'
```
The FSI intelligence endpoints use `company_id` + `api_key` in the request body. The VH3 FMS endpoints use `X-Api-Key` in the header. See [Authentication](/authentication) for full details.
## What's next?
How search, precedents, and customer knowledge work on the layer.
Endpoint reference for search and autocomplete.
Configure and query all 19 sentinel monitors.
Conversational AI with full operational context.
Generate and retrieve automated operational reports.