verification
use it
# add to stunt.yaml
services:
powerplatform:
adapter: embedded:powerplatform-style
# then
$ stunt upThe embedded: source extracts this adapter from the binary — no git clone, fully offline.
how to mock the Microsoft Power Platform API locally
Install stunt, paste the service block above into stunt.yaml, run stunt up — then point your client at localhost instead of Microsoft Power Platform API. It works offline, keeps state across requests and restarts, and every response is synthetic: the route shapes, status codes, pagination, and webhook delivery follow the real Microsoft Power Platform API 2 surface — the data is fake, the behavior is real.
backing stores
environmentsflows
api surface (9)
generated from the adapter manifest — exactly what boots, nothing more
9 routes
GET/v2/environments
GET/v2/environments/{env}/connectors
GET/v2/environments/{env}/api/data/v9.2/accounts
POST/v2/environments/{env}/api/data/v9.2/accounts
GET/v2/environments/{env}/api/data/v9.2/accounts({accountid})
PATCH/v2/environments/{env}/api/data/v9.2/accounts({accountid})
DELETE/v2/environments/{env}/api/data/v9.2/accounts({accountid})
GET/v2/environments/{env}/flows
POST/v2/environments/{env}/flows
VM-verified behaviors (19)
- ✓every route sits behind the entra bearer gate: a missing, non-bearer, or empty token answers 401 in the microsoft error envelope
- ✓the gate does not validate the token: any well-formed bearer passes (as-is)
- ✓environments list as the odata value envelope with arm resource ids and nested properties
- ✓the api-version query convention is not modeled: the param is ignored (version is baked into the /v2 path — reported)
- ✓environment lifecycle is not modeled: states are static and nothing moves on the clock (reported)
- ✓the collection lazily seeds two dataverse accounts on first read
- ✓create answers 201 with a location entity uri and OData-Version header, echoing the record
- ✓the accounts({accountid}) key convention retrieves and 404s with the dataverse 0x80040217 envelope
- ✓a client-supplied accountid is honored and targeted by later reads
- ✓patch is a partial merge answering 204; delete answers 204 and a second delete 404s
- ✓$filter supports eq/contains with AND and numeric comparisons on unquoted literals
- ✓$orderby sorts asc and desc; $skip applies before paging
- ✓$select projects fields and $count=true reports the post-filter pre-paging total
- ✓$top/$skipToken walk every account exactly once with @odata.nextLink only between pages
- ✓a nextLink round-trips the caller's $filter and $select so a paged walk stays filtered
- ✓paging is disabled without $top and an invalid skipToken answers 400 badrequest
- ✓an environment with no flows falls back to the seeded welcome flow
- ✓creating a flow persists it per environment behind arm flow ids; other environments keep the seeded fallback
- ✓connectors are static arm api resources with tiers
Not implemented (4)
- No environment lifecycle operations (create, update, delete)
- Only the accounts table is served — no contacts, leads, or other tables
- No flow update, delete, or run operations
- No $expand, $apply, or $search query options
Differs from the real API (6)
- No default page size: whole list returns unless $top is set; real Dataverse pages at 5000
- Client-supplied accountid accepted on create; auto ids are acc-<n>, not GUIDs
- Environments with no stored flows list a fallback seeded seeded-flow-001 entry
- api-version is ignored (version baked into the /v2 path); real Power Platform requires ?api-version=
- $skipToken is camelCase; real Dataverse entity paging uses $skiptoken
- POST accounts echoes the created record; real Dataverse returns 201 empty with OData-EntityId
want more of the Microsoft Power Platform API surface? adapters are YAML + Starlark — the authoring guide covers adding routes, fixtures, and state machines. Open an issue for anything big first, or just file a PR — merged routes ship in the next release.