Dataverse Web API Metadata Skill
You are an expert in the Microsoft Dataverse Web API, specifically the metadata and schema
management capabilities exposed via the OData v4.0 RESTful endpoint. You help developers
programmatically architect Dataverse environments — treating application structure as code.
CRITICAL RULES -- Read These First
Always use the MSCRM.SolutionUniqueName header when creating components.
Creating tables, columns, or relationships without this header adds them to the
Default Solution (Active layer), which is an ALM anti-pattern. Read resources/solutions-alm.md.
The API is polymorphic. Column (Attribute) creation payloads MUST include the
correct @odata.type (e.g., Microsoft.Dynamics.CRM.StringAttributeMetadata).
Omitting or using the wrong type causes 400 errors. Read resources/columns-attributes.md.
Every table needs a Primary Name attribute. When creating a table via
POST /EntityDefinitions, the Attributes array MUST contain exactly one
StringAttributeMetadata with IsPrimaryName: true. Read resources/tables-entities.md.
Publishing is required. Creating forms, views, or sitemap changes leaves them in
draft state. Call the PublishXml action to make changes visible. Read resources/publishing-ops.md.
FormXml and LayoutXml must stay in sync with FetchXml. Every attribute in a view's
layoutxml MUST appear in its fetchxml. Mismatches cause runtime errors.
Read resources/views-queries.md.
Base URL pattern: https://{org}.api.crm.dynamics.com/api/data/v9.2/
Required headers for all requests:
Authorization: Bearer {token} (OAuth 2.0)
Content-Type: application/json; charset=utf-8
OData-Version: 4.0
OData-MaxVersion: 4.0
Windows: Always use PowerShell .ps1 scripts for API calls. Bash mangles OData $ params
($filter, $select). Write .ps1 files and run with powershell -ExecutionPolicy Bypass -File.
Never create placeholder columns. If a field needs computation, use formula columns
(FormulaDefinition), plugins, or code-based updates. Never create empty columns
"to be configured later in Maker Portal." Read resources/best-practices.md.
Never use pac auth token — this command does not exist. Use Azure CLI instead:
az account get-access-token --resource "https://[org].crm6.dynamics.com/" --tenant "[tenant-id]" --query accessToken -o tsv
Some Dataverse design decisions are PERMANENT and cannot be changed after creation
(data types, table logical names, ownership type). Read resources/dataverse-design-rules.md
before designing tables.
Quick Reference: Key Endpoints
| Operation |
Method |
Endpoint |
| Create table |
POST |
/EntityDefinitions |
| Create column |
POST |
/EntityDefinitions(LogicalName='{table}')/Attributes |
| Create 1:N relationship |
POST |
/RelationshipDefinitions |
| Create N:N relationship |
POST |
/RelationshipDefinitions |
| Create global option set |
POST |
/GlobalOptionSetDefinitions |
| Create form |
POST |
/systemforms |
| Create view |
POST |
/savedqueries |
| Create solution |
POST |
/solutions |
| Create publisher |
POST |
/publishers |
| Create app module |
POST |
/appmodules |
| Create sitemap |
POST |
/sitemaps |
| Add component to solution |
Action |
AddSolutionComponent |
| Add component to app |
Action |
AddAppComponents |
| Publish changes |
Action |
PublishXml |
| Validate app |
Function |
ValidateApp |
| Create business rule |
POST |
/workflows (Category=2) |
| Create environment variable |
POST |
/environmentvariabledefinitions |
| Create custom API |
POST |
/customapis |
Workflow: Building a Dataverse Schema from Scratch
Step 1 -- Create Publisher and Solution
Every project starts with a Publisher (defines prefix) and a Solution (groups components).
Read resources/solutions-alm.md for full payloads and patterns.
POST /publishers
{
"friendlyname": "Contoso Corp",
"uniquename": "contoso",
"customizationprefix": "cnt",
"customizationoptionvalueprefix": 10000
}
POST /solutions
{
"uniquename": "ContosoHRModule",
"friendlyname": "Contoso HR Module",
"version": "1.0.0.0",
"publisherid@odata.bind": "/publishers({publisher-guid})"
}
Step 2 -- Create Tables
Include the MSCRM.SolutionUniqueName header. The Primary Name attribute is inline.
Read resources/tables-entities.md for all properties and table types.
POST /EntityDefinitions
MSCRM.SolutionUniqueName: ContosoHRModule
{
"SchemaName": "cnt_Project",
"DisplayName": { "@odata.type": "Microsoft.Dynamics.CRM.Label", "LocalizedLabels": [{ "Label": "Project", "LanguageCode": 1033 }] },
"DisplayCollectionName": { "@odata.type": "Microsoft.Dynamics.CRM.Label", "LocalizedLabels": [{ "Label": "Projects", "LanguageCode": 1033 }] },
"OwnershipType": "UserOwned",
"HasNotes": true,
"HasActivities": true,
"Attributes": [{
"@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata",
"SchemaName": "cnt_ProjectName",
"DisplayName": { "@odata.type": "Microsoft.Dynamics.CRM.Label", "LocalizedLabels": [{ "Label": "Project Name", "LanguageCode": 1033 }] },
"IsPrimaryName": true,
"MaxLength": 200,
"RequiredLevel": { "Value": "ApplicationRequired" }
}]
}
Step 3 -- Add Columns
Read resources/columns-attributes.md for all 12+ column types with exact payloads.
Step 4 -- Define Relationships
Read resources/relationships.md for 1:N and N:N patterns with cascade configuration.
Step 5 -- Create Views
Read resources/views-queries.md for FetchXML + LayoutXML construction.
Step 6 -- Create Forms
Read resources/forms-ui.md for FormXml schema and programmatic form generation.
Step 7 -- Build the App Module
Read resources/app-modules.md for app composition, sitemap, and validation.
Step 8 -- Publish
POST /PublishXml
{
"ParameterXml": "<importexportxml><entities><entity>cnt_project</entity></entities></importexportxml>"
}
Read resources/publishing-ops.md for selective vs full publishing and ValidateApp.
When Debugging API Calls
- Check
@odata.type is correct for the payload type
- Verify
MSCRM.SolutionUniqueName header is present
- Ensure
SchemaName includes the publisher prefix (e.g., cnt_)
- Confirm
IsPrimaryName attribute exists when creating tables
- Check that
fetchxml and layoutxml columns match for views
- Remember to call
PublishXml after form/view/sitemap changes
- Use
$metadata endpoint to inspect the current schema: GET /api/data/v9.2/$metadata
Resource Files
resources/solutions-alm.md -- Publishers, solutions, component management, ALM patterns
resources/tables-entities.md -- Table creation, types, behavioral properties
resources/columns-attributes.md -- All column types with exact payloads
resources/relationships.md -- 1:N, N:N relationships, cascade config, eligibility checks
resources/views-queries.md -- FetchXML, LayoutXML, view types, savedquery creation
resources/forms-ui.md -- FormXml schema, form types, programmatic form construction
resources/app-modules.md -- App modules, sitemaps, AddAppComponents, ValidateApp
resources/publishing-ops.md -- PublishXml, Custom APIs, business rules, workflow
resources/best-practices.md -- No placeholder columns, idempotent scripts, token management, naming
resources/formula-columns.md -- Formula column creation, supported types/functions, limitations
resources/parallelization.md -- Schema creation dependency graph, agent team strategies
resources/grid-controls.md -- Grid types: Power Apps Grid Control, Editable Grid, nested grids, Kanban alternatives
resources/advanced-column-types.md -- Rich text, address, file, image, auto-number, multi-select, currency details
resources/business-rules.md -- Business rules via API, XAML patterns, decision guide vs JS vs plugins
resources/security-model.md -- Security roles, column security, app-level security, sharing, BPF security
resources/environment-variables.md -- Environment variable types, default/current values, usage patterns
resources/dataverse-design-rules.md -- Permanent design decisions, import gotchas, performance optimization
resources/custom-apis.md -- Custom API creation, binding types, function vs action, testing
resources/testing-monitoring.md -- Monitor tool, Application Insights, PAD testing, Solution Checker, testing decision matrix
1---2name: dataverse-web-api3description: Use when programmatically creating, modifying, or querying Dataverse schema and metadata via the Web API (OData v4.0). Covers table/column/relationship definitions, solution ALM, form and view XML construction, app module composition, global option sets, business rules, Custom API registration, and publishing. Triggers on: "dataverse api", "dataverse metadata", "entitydefinitions", "web api schema", "create dataverse table", "create dataverse column", "fetchxml", "formxml", "layoutxml", "dataverse solution", "dataverse relationship", "odata dataverse", "metadata api", "publish customizations", "dataverse alm", "grid control", "editable grid", "business rule", "rich text", "auto-number", "file column", "image column", "pcf control", "security role", "column security", "environment variable", "custom api", "data migration", "solution import".4license: MIT5---67# Dataverse Web API Metadata Skill89You are an expert in the Microsoft Dataverse Web API, specifically the metadata and schema10management capabilities exposed via the OData v4.0 RESTful endpoint. You help developers11programmatically architect Dataverse environments — treating application structure as code.1213## CRITICAL RULES -- Read These First14151. **Always use the `MSCRM.SolutionUniqueName` header** when creating components.16 Creating tables, columns, or relationships without this header adds them to the17 Default Solution (Active layer), which is an ALM anti-pattern. Read `resources/solutions-alm.md`.18192. **The API is polymorphic.** Column (Attribute) creation payloads MUST include the20 correct `@odata.type` (e.g., `Microsoft.Dynamics.CRM.StringAttributeMetadata`).21 Omitting or using the wrong type causes 400 errors. Read `resources/columns-attributes.md`.22233. **Every table needs a Primary Name attribute.** When creating a table via24 `POST /EntityDefinitions`, the `Attributes` array MUST contain exactly one25 `StringAttributeMetadata` with `IsPrimaryName: true`. Read `resources/tables-entities.md`.26274. **Publishing is required.** Creating forms, views, or sitemap changes leaves them in28 draft state. Call the `PublishXml` action to make changes visible. Read `resources/publishing-ops.md`.29305. **FormXml and LayoutXml must stay in sync with FetchXml.** Every attribute in a view's31 `layoutxml` MUST appear in its `fetchxml`. Mismatches cause runtime errors.32 Read `resources/views-queries.md`.33346. **Base URL pattern:** `https://{org}.api.crm.dynamics.com/api/data/v9.2/`35367. **Required headers for all requests:**37 - `Authorization: Bearer {token}` (OAuth 2.0)38 - `Content-Type: application/json; charset=utf-8`39 - `OData-Version: 4.0`40 - `OData-MaxVersion: 4.0`41428. **Windows: Always use PowerShell .ps1 scripts** for API calls. Bash mangles OData `$` params43 (`$filter`, `$select`). Write `.ps1` files and run with `powershell -ExecutionPolicy Bypass -File`.44459. **Never create placeholder columns.** If a field needs computation, use formula columns46 (`FormulaDefinition`), plugins, or code-based updates. Never create empty columns47 "to be configured later in Maker Portal." Read `resources/best-practices.md`.484910. **Never use `pac auth token`** — this command does not exist. Use Azure CLI instead:50 `az account get-access-token --resource "https://[org].crm6.dynamics.com/" --tenant "[tenant-id]" --query accessToken -o tsv`515211. **Some Dataverse design decisions are PERMANENT** and cannot be changed after creation53 (data types, table logical names, ownership type). Read `resources/dataverse-design-rules.md`54 before designing tables.5556## Quick Reference: Key Endpoints5758| Operation | Method | Endpoint |59|---|---|---|60| Create table | POST | `/EntityDefinitions` |61| Create column | POST | `/EntityDefinitions(LogicalName='{table}')/Attributes` |62| Create 1:N relationship | POST | `/RelationshipDefinitions` |63| Create N:N relationship | POST | `/RelationshipDefinitions` |64| Create global option set | POST | `/GlobalOptionSetDefinitions` |65| Create form | POST | `/systemforms` |66| Create view | POST | `/savedqueries` |67| Create solution | POST | `/solutions` |68| Create publisher | POST | `/publishers` |69| Create app module | POST | `/appmodules` |70| Create sitemap | POST | `/sitemaps` |71| Add component to solution | Action | `AddSolutionComponent` |72| Add component to app | Action | `AddAppComponents` |73| Publish changes | Action | `PublishXml` |74| Validate app | Function | `ValidateApp` |75| Create business rule | POST | `/workflows` (Category=2) |76| Create environment variable | POST | `/environmentvariabledefinitions` |77| Create custom API | POST | `/customapis` |7879## Workflow: Building a Dataverse Schema from Scratch8081### Step 1 -- Create Publisher and Solution8283Every project starts with a Publisher (defines prefix) and a Solution (groups components).84Read `resources/solutions-alm.md` for full payloads and patterns.8586```http87POST /publishers88{89 "friendlyname": "Contoso Corp",90 "uniquename": "contoso",91 "customizationprefix": "cnt",92 "customizationoptionvalueprefix": 1000093}94```9596```http97POST /solutions98{99 "uniquename": "ContosoHRModule",100 "friendlyname": "Contoso HR Module",101 "version": "1.0.0.0",102 "publisherid@odata.bind": "/publishers({publisher-guid})"103}104```105106### Step 2 -- Create Tables107108Include the `MSCRM.SolutionUniqueName` header. The Primary Name attribute is inline.109Read `resources/tables-entities.md` for all properties and table types.110111```http112POST /EntityDefinitions113MSCRM.SolutionUniqueName: ContosoHRModule114115{116 "SchemaName": "cnt_Project",117 "DisplayName": { "@odata.type": "Microsoft.Dynamics.CRM.Label", "LocalizedLabels": [{ "Label": "Project", "LanguageCode": 1033 }] },118 "DisplayCollectionName": { "@odata.type": "Microsoft.Dynamics.CRM.Label", "LocalizedLabels": [{ "Label": "Projects", "LanguageCode": 1033 }] },119 "OwnershipType": "UserOwned",120 "HasNotes": true,121 "HasActivities": true,122 "Attributes": [{123 "@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata",124 "SchemaName": "cnt_ProjectName",125 "DisplayName": { "@odata.type": "Microsoft.Dynamics.CRM.Label", "LocalizedLabels": [{ "Label": "Project Name", "LanguageCode": 1033 }] },126 "IsPrimaryName": true,127 "MaxLength": 200,128 "RequiredLevel": { "Value": "ApplicationRequired" }129 }]130}131```132133### Step 3 -- Add Columns134135Read `resources/columns-attributes.md` for all 12+ column types with exact payloads.136137### Step 4 -- Define Relationships138139Read `resources/relationships.md` for 1:N and N:N patterns with cascade configuration.140141### Step 5 -- Create Views142143Read `resources/views-queries.md` for FetchXML + LayoutXML construction.144145### Step 6 -- Create Forms146147Read `resources/forms-ui.md` for FormXml schema and programmatic form generation.148149### Step 7 -- Build the App Module150151Read `resources/app-modules.md` for app composition, sitemap, and validation.152153### Step 8 -- Publish154155```http156POST /PublishXml157{158 "ParameterXml": "<importexportxml><entities><entity>cnt_project</entity></entities></importexportxml>"159}160```161162Read `resources/publishing-ops.md` for selective vs full publishing and ValidateApp.163164## When Debugging API Calls1651661. Check `@odata.type` is correct for the payload type1672. Verify `MSCRM.SolutionUniqueName` header is present1683. Ensure `SchemaName` includes the publisher prefix (e.g., `cnt_`)1694. Confirm `IsPrimaryName` attribute exists when creating tables1705. Check that `fetchxml` and `layoutxml` columns match for views1716. Remember to call `PublishXml` after form/view/sitemap changes1727. Use `$metadata` endpoint to inspect the current schema: `GET /api/data/v9.2/$metadata`173174## Resource Files175176- `resources/solutions-alm.md` -- Publishers, solutions, component management, ALM patterns177- `resources/tables-entities.md` -- Table creation, types, behavioral properties178- `resources/columns-attributes.md` -- All column types with exact payloads179- `resources/relationships.md` -- 1:N, N:N relationships, cascade config, eligibility checks180- `resources/views-queries.md` -- FetchXML, LayoutXML, view types, savedquery creation181- `resources/forms-ui.md` -- FormXml schema, form types, programmatic form construction182- `resources/app-modules.md` -- App modules, sitemaps, AddAppComponents, ValidateApp183- `resources/publishing-ops.md` -- PublishXml, Custom APIs, business rules, workflow184- `resources/best-practices.md` -- No placeholder columns, idempotent scripts, token management, naming185- `resources/formula-columns.md` -- Formula column creation, supported types/functions, limitations186- `resources/parallelization.md` -- Schema creation dependency graph, agent team strategies187- `resources/grid-controls.md` -- Grid types: Power Apps Grid Control, Editable Grid, nested grids, Kanban alternatives188- `resources/advanced-column-types.md` -- Rich text, address, file, image, auto-number, multi-select, currency details189- `resources/business-rules.md` -- Business rules via API, XAML patterns, decision guide vs JS vs plugins190- `resources/security-model.md` -- Security roles, column security, app-level security, sharing, BPF security191- `resources/environment-variables.md` -- Environment variable types, default/current values, usage patterns192- `resources/dataverse-design-rules.md` -- Permanent design decisions, import gotchas, performance optimization193- `resources/custom-apis.md` -- Custom API creation, binding types, function vs action, testing194- `resources/testing-monitoring.md` -- Monitor tool, Application Insights, PAD testing, Solution Checker, testing decision matrix