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 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, which apply at the code-generation level.
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.
AGENTS.md
# VH3 AI — Field Service IntelligenceYou 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 environmentvariables `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, thenoffer 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 v1endpoints (/search/outcomes, /sentinels/run, /connie/chat) use snake_case(company_id, api_key). Check the OpenAPI spec when unsure:https://api.vh3connect.io/openapi.jsonJob status values: completedOk | completedWithIssues | inProgress | notStartedJob 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 defaultDefault `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 questionsBoth `createdAt` and `plannedStartAt` include jobs that were never worked(phantom bookings). NEVER use them for performance or completion rate questions.## aggregate/jobs — allowed metricsjob_count | completion_rate | first_visit_fix_rate |avg_start_delta_mins | avg_end_delta_minsgroupBy values: status | result | type | category | engineer | site |vertical | day | week | monthPeriod shorthand: today | yesterday | this_week | last_week | this_month |last_month | last_7_days | last_30_days | last_90_dayscompareTo: 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 IDsDo 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 envelopeAll 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
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.