add-ai-webapi
SkillSearchIntegrates Power Pages generative-AI summarization APIs (PREVIEW) into a Single Page Application (SPA) site — the Search Summary API and the Data Summarization API — on any record-detail or list page. Generates per-target service code (CSRF-handled) and AI site settings; delegates Web API settings, table permissions, and web roles to `/integrate-webapi` and `/create-webroles`. Use whenever a user wants AI/Copilot output that condenses Dataverse content on a Power Pages site — an AI summary, AI-generated overview or "key insights" across a record or list, a search-results summary, a case/incident summary, or recommendation-chip refinement — even when phrased as "AI-generated paragraph", "insights", or "overview". Do NOT use for: generative pages in model-driven apps (use the model-apps `genpage` skill), Copilot Studio agents/chatbots, summarizing documents or PDFs, Power BI dashboards, plain keyword search with no AI summary, or plain Dataverse CRUD (use `/integrate-webapi`).
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the add-ai-webapi skill
What this skill tells your AI
The instructions your AI receives, as published by microsoft/power-platform-skills in plugins/power-pages/skills/add-ai-webapi/SKILL.md and read by ahel’s review.
Plugin check: Run
node "${PLUGIN_ROOT}/scripts/check-version.js"— if it outputs a message, show it to the user before proceeding.
Add AI Web API
Note
AI summarization APIs are a preview feature. Preview features aren't meant for production use and may have restricted functionality. These features are available before an official release so that customers can get early access and provide feedback.
Surface this note to the user verbatim during Phase 1 and again in the Phase 8 summary —
copy the exact **Note** block above (including its wording about "available before an official
release so that customers can get early access and provide feedback"). Do not paraphrase it into
your own "Preview-feature note: ..." sentence; the wording matches the Microsoft Learn preview
disclaimer and rephrasing it loses that fidelity.
Integrate Power Pages generative-AI summarization APIs into a SPA site. This skill focuses on the AI layer (Layer 3): the summarization service code and the Summarization/* site settings. The underlying Web API prerequisites — Webapi/<table>/enabled, Webapi/<table>/fields, table permissions, and web roles — are delegated to /integrate-webapi and /create-webroles so there is a single source of truth for every layer.
The two APIs covered
| # | API | URL | Body | Response |
|---|---|---|---|---|
| 1 | Search Summary | POST /_api/search/v1.0/summary | { userQuery } | { Summary, Citations } |
| 2 | Data Summarization | POST /_api/summarization/data/v1.0/<entitySet>(<id>)?$select=...&$expand=... | { InstructionIdentifier } or { RecommendationConfig } | { Summary, Recommendations } |
Example: Microsoft-shipped Copilot summary on a support-case page. Data Summarization can be called with any combination of entity set, columns, and prompt — but Microsoft documents and ships one specific configuration for the standard
incidenttable:POST /_api/summarization/data/v1.0/incidents(<caseId>)?$select=description,title&$expand=incident_adx_portalcomments($select=description)with body{ "InstructionIdentifier": "Summarization/prompt/case_summary" }. This is sometimes called the "Case-page Copilot preset" in Microsoft Learn. Treat it as one possible Data Summarization recipe — useful when the user explicitly wants to mirror the Microsoft sample — not as an automatic recommendation. A custom case-like table (cr363_servicerequest,adx_case), or the standard incident table summarised on different facets (priority, owner, SLA timer), is just a regular Data Summarization call with maker-defined values.
Reference:
${PLUGIN_ROOT}/skills/add-ai-webapi/references/ai-api-reference.md— canonical API shapes, required headers, site-setting names, error codes, and the documented support-case example. Read this at the start of the workflow; fetch the Microsoft Learn source pages withmcp__plugin_power-pages_microsoft-learn__microsoft_docs_fetchif the user asks for the latest.
Admin governance hierarchy: both APIs are gated by a three-level admin hierarchy — tenant PowerShell setting (
enableGenerativeAIFeaturesForSiteUsers), Copilot Hub environment/site governance, and the site-level maker toggle (for Search Summary: Set up workspace → Copilot → Site search (preview) → Enable Site search with generative AI (preview)). Each level overrides the one below it, so "the maker toggle is on but the API still says disabled" is a real scenario — admin-level governance wins.The two endpoints surface disablement differently:
- Search Summary → HTTP 200 with an embedded envelope
{ Code: 400, Message: "Gen AI Search is disabled." }. The generatedfetchSearchSummarydetects this and throwsSearchSummaryApiError; the UI renders a remediation card.- Data Summarization → HTTP 400 with
error.code = 90041001(admin-level disabled) or90041003(per-siteSummarization/Data/Enable=false).Full troubleshooting checklist (tenant → environment → site, plus runtime version, Bing dependency, and cross-region data movement) lives in
references/ai-api-reference.md§1 "Troubleshooting: AI feature appears disabled (admin hierarchy)" — point users there when either disablement shape surfaces. Mention this governance hierarchy explicitly to the user before Phase 7, and again in the Phase 8 summary.
Built-in search control vs. custom code path: if the site uses the Microsoft-shipped Power Pages search control and only wants AI-summarised search results on that page, they don't need this skill — just the Copilot workspace toggle and the
Search/Summary/Titlecontent snippet. This skill is for sites that build their own search UI or need to call/_api/search/v1.0/summaryfrom custom code. Confirm which path the user is on in Phase 1.
Core principles
- Layer 3 only, delegate the rest. Web API site settings, table permissions, and web roles all belong to
/integrate-webapiand/create-webroles. This skill creates the summarization service code and theSummarization/*site settings — nothing else. - Sequential agent spawning. Per
plugins/power-pages/AGENTS.md, spawn theai-webapi-integrationagent sequentially per target (never in parallel). The first call establishes the shared summarization service file and CSRF helper; subsequent calls extend it.ai-webapi-settings-architectruns alone, after all code integrations land. - Raw
fetch+ CSRF. Every summarization request attaches__RequestVerificationToken(from/_layout/tokenhtml) andX-Requested-With: XMLHttpRequest. Never route through an OData wrapper. - Skip
/integrate-webapiwhen it's not needed. If every confirmed target is Search Summary (which has no per-table Web API prerequisites), or every Layer 1/2 prerequisite already exists on disk, the skill goes straight from Phase 3 to Phase 5. - Use TaskCreate/TaskUpdate — create the todo list upfront with all phases before starting.
Prerequisites:
- An existing Power Pages SPA site created via
/create-site- A Dataverse data model (tables + columns) set up via
/setup-datamodelor manually — for any Data Summarization target- The site must have been deployed at least once (
.powerpages-sitefolder must exist) for the settings phase
Initial request: $ARGUMENTS
Workflow
(Phase headings below the workflow keep the technical "Layer 1+2 / Layer 3" names because they describe the runtime layering and are what maintainers grep for. The titles here mirror the user-facing task list.)
- Check site is ready — locate project, detect framework, check data model, deployment status, and web-role presence.
- Find where AI summaries fit — scan code for search / data summarization candidates.
- Confirm what to add — review the manifest and pick which APIs / targets to integrate.
- Set up data access for AI — invoke
/create-webrolesif needed, then invoke/integrate-webapiin AI-only read mode for data/case targets. Skip entirely for search-only or when prerequisites already exist. - Add AI summary code — invoke the
ai-webapi-integrationagent sequentially per target. - Register AI prompts — invoke the
ai-webapi-settings-architectagent. - Verify everything — header-contract grep,
$selectgrep,npm run build, validator script. - Review and deploy — record skill usage, summarise, offer
/deploy-site.
Iteration mode (after first run)
This skill is a one-shot setup skill — Phases 1–8 run end-to-end the first time the user asks
to integrate a summarization API. Once an AI surface is in place (service file, framework wrapper,
UI call site, and Summarization/* settings all exist), follow-up requests to tweak the rendered
UI (colours, spacing, copy, moving a button, a different empty-state message, wiring a second
recommendation into the hook, etc.) are not a reason to re-enter this skill mentally and run
every phase again. Doing so triggers a full pac pages upload-code-site and a chain of
git commits for each tweak, which is exactly the noisy cadence the Phase 5.5 / 6.4 prompts above
are there to avoid.
When the user asks for follow-up UI changes to an already-integrated AI surface:
- Edit the file(s) and run
npm run buildlocally to verify the tweak compiles. That is the whole validation loop for a UI change. - Do NOT automatically run
pac pages upload-code-site. Uploading should happen once, at the end of the session, when the user has finished tweaking. - Do NOT automatically
git commit. Let the user batch related tweaks into a single commit. - Batch the deployment and commit into a single end-of-session prompt once the user signals they're done (or when you've completed the last requested change).
🚦 Gate (consent · add-ai-webapi:iter.deploy-commit): End-of-iteration batched deploy + commit prompt — avoids a noisy per-tweak upload/commit cadence.
Trigger: User signals they're done with UI tweaks for the session. Why we ask: Auto-deploying or committing after every small edit produces one
git commit+ onepac pages upload-code-siteper tweak; batching keeps history readable and avoids redundant deploys. Cancel leaves: Nothing — source files already edited; no deploy or commit fired.
Use AskUserQuestion:
| Question | Header | Options |
|---|---|---|
| All the UI tweaks look good. Deploy the site and commit the changes now? | Deploy & commit | Yes, deploy and commit (Recommended), Just commit — I'll deploy later, Just deploy — I'll commit later, Neither — I'll handle both myself |
Re-enter the full skill flow only when the user is adding a new AI surface (a new page, a new table, a second API). If you're unsure whether a request is a tweak or a new surface, ask.
Phase 1: Verify Site Exists
Goal: Locate the Power Pages project root and confirm prerequisites.
1.0 Detect iteration mode (before anything else)
Re-entry detection comes first because the rest of the skill assumes a first-time setup. Capture two signals about the project state:
- Service signal: a summarization service exists —
src/services/aiSummaryService.*, or any source file undersrc/that contains/_api/search/v1.0/summaryor/_api/summarization/data/v1.0/. When the signal is present, also note which API surface(s) the service code references — search-only, data-only, or both. This sub-classification matters below. - Settings signal: at least one Layer 3 site setting exists in
.powerpages-site/site-settings/Summarization-*.sitesetting.yml.
Then route on the combination:
- Both signals present → re-entry. A previous
/add-ai-webapirun completed end-to-end. Show the iteration-mode prompt below. - Service signal present and the existing service code is search-only (it references
/_api/search/v1.0/summarybut not/_api/summarization/data/v1.0/) → re-entry. Search-only sites legitimately have noSummarization/*settings (Search Summary uses the workspace toggle, not per-call settings), so the absence of the settings signal is the steady state, not a failed run. Show the iteration-mode prompt below. - Service signal present and the existing service code includes Data Summarization but the settings signal is absent → in-flight first run (a previous attempt failed before Phase 6 landed). Continue with the full flow without prompting.
- Neither signal present → first-time run. Continue with Phase 1.1.
When you reach the iteration-mode branch, ask:
| Question | Header | Options |
|---|---|---|
| It looks like an AI summary surface is already wired into this site. Is this request a tweak to the existing one, or are you adding a brand-new surface (new page, new table, second API)? | Mode | Tweak the existing surface (Recommended for visual/copy edits), Add a new surface (run the full skill again), Not sure — show me what's already wired |
- Tweak the existing surface: stop running this skill. Switch into the workflow described in
the Iteration mode section above — Edit +
npm run build, no auto upload-code-site, no auto commit, batched end-of-session prompt for deploy + commit. - Add a new surface: continue with Phase 1.1 (full flow). The downstream phases will detect existing infrastructure (CSRF helper, summarization service, settings) and extend rather than duplicate.
- Not sure — show me what's already wired: list the existing service file(s), wired UI
components, and
Summarization/*settings, then re-ask the same question.
1.1 Create todo list
Create all 8 phase tasks upfront via TaskCreate — see Progress Tracking.
1.2 Locate project
Look for powerpages.config.json in the current directory or immediate subdirectories.
If not found: tell the user to create a site first with /create-site.
1.3 Detect framework
Read package.json and detect React / Vue / Angular / Astro. See
${PLUGIN_ROOT}/references/framework-conventions.md.
1.4 Check for data model
Look for .datamodel-manifest.json. If found, read it — tables listed here are candidates for the
Data Summarization API. The standard incident table is a candidate like any other; do not
treat it specially.
1.5 Check deployment status — hard prerequisite
Look for .powerpages-site. Phase 4 (/integrate-webapi) and Phase 6 (ai-webapi-settings-architect)
both require this folder to exist. Deferring the deploy until later is not a viable workaround:
once Phase 5 has written the AI-calling service code, deploying a site whose Layer 1/2/3 settings
aren't yet on disk publishes runtime-broken code (every summarization call 403/500s until a second
deploy lands). The cleanest sequence is to deploy the clean scaffold now, before any AI code
exists.
If .powerpages-site does NOT exist:
| Question | Header | Options |
|---|---|---|
.powerpages-site was not found. The AI summary skill needs the site deployed at least once before configuring permissions and settings. Deploy the clean scaffold now (no AI code yet — keeps the intermediate state safe), or stop and run /deploy-site yourself first? | Bootstrap deploy | Yes, deploy the scaffold now (Recommended), Stop — I'll deploy first then re-run /add-ai-webapi |
On Yes: invoke the Skill tool for power-pages:deploy-site and wait for completion. Then
re-check .powerpages-site exists before proceeding. If it is still absent after the
sub-skill returns (deploy failed mid-flow, the user cancelled it, or an upload completed but the
local folder wasn't created), stop here with a clear message — surface the deploy-site outcome
verbatim so the user can debug it, and tell them to re-run /deploy-site followed by
/add-ai-webapi. Do NOT silently fall through to Phase 2; the downstream sub-skills require this
folder.
On Stop: end the skill with a clear next-step message ("Run /deploy-site, then re-invoke
/add-ai-webapi to continue"). Do NOT continue to Phase 2 — the downstream sub-skills can't run.
1.6 Check web roles
Look for .powerpages-site/web-roles/*.yml. Record whether any roles exist — the Phase 4
delegation needs at least one role before /integrate-webapi can create table permissions.
Output: confirmed project root, framework, data-model availability, deployment status, web-role inventory.
Phase 2: Explore AI integration points
Goal: Find every candidate for each of the two APIs — scoped to AI only.
The full Explore-agent prompt body, manifest shape, and delegation-decision rules live in
${PLUGIN_ROOT}/skills/add-ai-webapi/references/explore-prompt.md. Read that file
first, then invoke the Explore agent (via Task with subagent_type: "Explore",
thoroughness medium) and pass the prompt body verbatim.
What the Explore agent reports back (summary — see the reference for the exact prompt):
- Reserved-slot markers (
POWERPAGES:AI-SLOT kind=<pick>) — authoritative placement hints planted by/create-site; orphan markers are flagged for Phase 3 to resolve. - Search Summary candidates including related-record-discovery targets on detail pages ("suggested KB articles", "similar cases").
- Data Summarization candidates classified
single-record/list/intent-mismatch, each with the existing fetch's OData query and a scope classification (matches-existing-fetch/scope-extends-beyond-existing-fetch/needs-definition/intent-mismatch). - Existing infrastructure — CSRF helper,
powerPagesApi.ts, prioraiSummaryService.*. - Layer 1/2 status per Data Summarization target plus every
$expandtarget —ready/missing/n/a (search). - Fields-list breadth advisory — for Layer 1/2
readyrows whose existingWebapi/<table>/fieldsis broader than the AI surface needs (primary key included, relationship Navigation Properties unused by@odata.bind, unused columns), flaggedfields-broader-than-ai-modeso Phase 3 can surface it. - Layer 3 status per Data Summarization target —
Summarization/Data/Enableand the specificSummarization/prompt/<id>the code will send.
Compile the integration manifest from the agent's output (one row per candidate, columns:
#, API, Target file, Target kind, Entity Set, $select / $expand, Source,
Layer 1/2 status, Layer 3 status) — the reference file contains a worked example.
Delegation decisions (compute directly from the status columns):
- Run
/integrate-webapi? → True if any row's Layer 1/2 status ismissing. Send only the missing-status rows in thetables=sentinel; don't re-audit settled tables. - Run
ai-webapi-settings-architect? → True if any row's Layer 3 status ismissing.
Output: integration manifest + delegation decisions + existing-infra report + fields-broader-than-ai-mode advisory list (if any).
Phase 3: Review AI plan
Goal: Present the manifest and confirm which APIs / targets to integrate.
Show the user:
- The list of APIs and targets found.
- For each: which file references it and what the service will do.
- The two delegation decisions from Phase 2 ("Will invoke
/integrate-webapifor [tables]", "Will invokeai-webapi-settings-architectfor Layer 3"). - Existing-infrastructure notes (CSRF helper reuse,
powerPagesApi.ts, previousaiSummaryService.*).
Approval cadence (set expectations up-front)
Before asking the integration question, briefly tell the user how many more decision points are coming so the "one-shot" run isn't surprising. Count them from the Key decision points list, subtracting the ones that don't apply for this run:
- Search-only run: drop the
/integrate-webapidelegation (Phase 4) and the settings architect (Phase 6) — 4–5 more pauses after this one. - Layer 1/2 already ready: drop the Phase 4.3 architect approvals.
- No list / scope-extends / intent-mismatch rows: drop the per-target Phase 3 follow-ups.
- First-time run with all branches firing: 7–10 more pauses (web-role choice, per-target list-trigger and scope-confirmation, two integrate-webapi architect plans, the AI settings architect plan, two commit prompts, final deploy).
Phrase it as a heads-up, not a warning — e.g., "I'll pause for your input ~6 more times after this one (web-role choice, two architect plans, two commit prompts, final deploy). Could be a couple more if any list target needs a trigger or scope decision."
The integration question
Use AskUserQuestion and build the option list dynamically from the Phase 2 manifest — do
not hardcode "Search summary and Data summarization" when only one category has candidates.
Construct the question text from what was found:
- If both categories have candidates: "I found candidates for Search Summary and Data Summarization. Which should I integrate?"
- If only one category with one target: skip "All of them" — just confirm the single target
("Wire Search Summary into
<page>?").
The default option list, with rows present only when the corresponding category has candidates:
| Option | When to include |
|---|---|
| All of them (Recommended) | Both categories present |
| Only Search Summary | Search candidates present AND Data Summarization candidates present |
| Only Data Summarization | Data Summarization candidates present AND Search candidates present |
| Let me select specific ones | Always (multi-target runs) |
| None — cancel | Always |
If the user chooses "Let me select specific ones", follow up with a multi-select question listing each row of the integration manifest. When a detail-page candidate was flagged in Phase 2 as a related-record-discovery target, include it as a dedicated option (in addition to any Data Summarization option for the same page) so the user can consciously pick the AI-grounded path rather than a hand-rolled OData match — e.g.:
Search Summary on CaseDetail.tsx (finds related KB articles via generative AI)Search Summary on ProductDetail.tsx (finds related products via generative AI)
Label the option with the page name and the outcome it produces, not just "Search Summary", so the user sees exactly where the AI surface will appear.
Per-target follow-up questions
After the user confirms targets, ask per-target follow-up questions only when needed:
- List-trigger — every list target gets a "load on open" vs "manual button" question.
- Scope confirmation — only when Phase 2 flagged the row
scope-extends-beyond-existing-fetch,needs-definition, orintent-mismatch. Resolveintent-mismatchfirst because the chosen target kind decides which scope question (LIST or SINGLE-RECORD) to ask next.
Question text, option lists, and the scope-classification → question mapping live in
${PLUGIN_ROOT}/skills/add-ai-webapi/references/scope-classification.md. Read it
when any per-target follow-up is required.
The chosen values flow into the Phase 5 agent-invocation prompt as the Scope for the summary
call block ($filter, $orderby, Scope source, Target's existing list fetch). The
existing UI fetch on the target component stays in place unchanged — the summary URL is an
addition, never a replacement.
If the user picks a scope that adds new $expand targets (e.g., "include its line items"),
re-evaluate the Phase 2 Layer 1/2 delegation decision — the new expansion is a new
prerequisite (Web API enabled + parent-scope permission on the child table).
Handling "None — cancel"
When the user picks None — cancel:
- Mark the remaining tasks as
completedwith a(skipped — cancelled by user)suffix in the activeForm so the task list reads cleanly rather than leaving them stuckpending. - Jump straight to Phase 8.1 (record skill usage with
--skillName "AddAiWebapi"and an outcome ofcancelled) and Phase 8.2 (present a one-line summary: "No changes made — you cancelled at the plan-review step"). - Skip Phases 4, 5, 6, 7, and 8.3 entirely. Do not invoke
/integrate-webapi,ai-webapi-integration,ai-webapi-settings-architect, or/deploy-site. Do not commit.
Output: user-confirmed integration manifest, or a clean cancellation.
Phase 4: Delegate Layer 1 + Layer 2
Goal: Ensure every Web API prerequisite for the AI target tables exists, by delegating to
/create-webroles and /integrate-webapi (AI-only read mode) instead of writing Layer 1/2 files
directly.
4.1 Skip-check
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 859
- Forks
- 176
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
add-ai-webapi- Source
- github.com/microsoft/power-platform-skills