PL-400: Power Platform Developer Study Guide
The PL-400: Microsoft Power Platform Developer exam validates your ability to extend Power Platform with pro-code: Dataverse plug-ins, client scripting and PCF controls, custom connectors, and external integrations. It targets developers who design and build solutions on Dataverse, Power Apps, and Power Automate, and who manage application lifecycle. Expect 40-60 questions in 120 minutes, with a scaled passing score of 700.
Domain 1: Application Lifecycle Management
- Prefer low-code (business rules, calculated/rollup columns, flows) over pro-code; only write plug-ins when requirements exceed declarative capabilities (complex server logic, integrations, strict performance needs).
- Solutions are the unit of packaging: develop in unmanaged solutions, deploy managed solutions downstream. Managed solutions are read-only in target environments and support clean uninstall.
- Never hardcode secrets in code or solutions; store them as environment variables backed by Azure Key Vault references, never embedding the raw secret value.
- Use the Power Platform CLI (pac) for ALM: pac auth create --url, pac solution export/import, pac solution unpack/pack with --packagetype Both|Managed|Unmanaged.
- pac solution import --path MySolution.zip --async --max-async-wait-time 60 imports asynchronously; pac solution unpack --packagetype Both produces source you can commit to version control.
- Automate deployments with Power Platform Build Tools for Azure DevOps or the Power Platform GitHub Actions; these wrap pac CLI tasks like who-am-i, export, import, and pack/unpack.
- Import dependent (parent) solutions before solutions that reference them; missing dependencies cause import failure.
- Use segmented (partial) solutions that contain only the changed components instead of full exports to reduce import time and risk.
- Use separate environments per stage (dev, test, prod). Developer environments are free, single-user, and can be reset or deleted when no longer needed.
- Apply Data Loss Prevention (DLP) policies and least-privilege security roles to govern connectors and protect data across environments.
- Govern environments with environment-creation policies (Power Platform admin center) and routinely delete or reset unused dev/trial environments to control sprawl.
- Avoid unnecessary synchronous plug-in steps and design against infinite trigger loops (e.g., a plug-in on Update that updates the same record without filtering attributes).
- Configure audit retention and auto-deletion policies, and tune plug-in trace log retention, to manage storage and meet governance requirements.
- Monitor with Power Platform admin center analytics, plug-in trace logs, and Application Insights integration for telemetry on flows and apps.
Domain 2: Extend the User Experience
- JavaScript is the only supported language for client-side logic in model-driven forms; it runs in the browser on events like OnLoad, OnChange, and OnSave via the Client API.
- Retrieve the form context with executionContext.getFormContext(); pass executionContext as the first parameter to handlers and avoid the deprecated global Xrm.Page.
- Common Client API calls: formContext.getAttribute("telephone1").setRequiredLevel("required"); formContext.getControl("creditlimit").setVisible(false); formContext.data.entity.getId() returns the record GUID.
- Power Apps Component Framework (PCF) builds reusable code components in TypeScript/React for both canvas and model-driven apps; the framework calls init, updateView, getOutputs, and destroy in the control lifecycle.
- In a PCF dataset component, request only needed columns and use delegable queries with filters/Top so paging happens server-side; minimize work inside updateView since it is called frequently.
- Calculated columns automatically compute and store a value when a record is created or updated, with no code; they are the lowest-maintenance choice when the formula fits supported functions.
- Rollup columns aggregate values from related child records (sum, count, min, max, avg) and refresh on a system schedule rather than instantly.
- A synchronous plug-in on Create and Update can populate a column before save when the calculation exceeds what calculated columns support, at the cost of added complexity and performance.
- For canvas apps, favor delegable data sources and functions so filtering happens at the source; non-delegable operations are capped at the data row limit (default 500, max 2000).
- Use asynchronous Web API calls and request only required columns; defer non-essential data with lazy loading (load a screen's data only when navigated to).
- Cache reference data once in a variable or collection and reuse it instead of re-querying on every interaction.
- Business rules provide no-code field logic (show/hide, require, set value, validate) that runs on the client and, for some scopes, on the server, without JavaScript.
- Form scripts and PCF components are distributed as web resources packaged inside solutions, keeping them under ALM and version control.
- Use named formulas and consistent naming for reusable Power Fx logic to keep canvas apps maintainable.
Domain 3: Extend the Platform
- Dataverse plug-ins are .NET assemblies that run server-side on the event pipeline in response to messages (Create, Update, Delete, Retrieve, RetrieveMultiple, custom messages).
- The pipeline has stages: pre-validation (stage 10, outside the database transaction), pre-operation (stage 20, inside the transaction before commit), and post-operation (stage 40, after commit).
- The platform passes IPluginExecutionContext carrying InputParameters (including the Target entity), OutputParameters, pre/post entity images, MessageName, Depth, and the initiating/user IDs.
- Throw InvalidPluginExecutionException in pre-validation or pre-operation to cancel an operation and surface a validation error to the user.
- Plug-ins run in a sandbox with a hard 2-minute execution limit and restricted resources; offload long-running or heavy integration work to async flows, async plug-ins, or Azure Functions.
- Register plug-in steps and images with the Plug-in Registration Tool (or pac plugin), specifying message, primary entity, stage, execution mode (sync/async), and filtering attributes.
- Register and read a pre-image instead of issuing a Retrieve to get prior values, reducing round-trips and improving performance.
- Specify filtering attributes on an Update step so the plug-in fires only when the relevant columns change, preventing needless executions and trigger loops.
- Use SharedVariables on the context to pass data between plug-in steps/stages within the same pipeline execution.
- For bulk server-side work use ExecuteMultipleRequest for batching mixed requests, or the optimized CreateMultiple/UpdateMultiple messages for same-table bulk operations.
- Detect bulk or unwanted invocations via the execution context (e.g., check Depth, message, or a custom 'suppress' flag in SharedVariables) and exit early to avoid recursion.
- Query efficiently with QueryExpression or FetchXML using column subsets and paging; on the Web API use $select to return only needed columns and $top for paging.
- Custom APIs and custom actions expose callable server-side logic as endpoints invokable from clients, flows, and integrations, with defined request/response parameters.
- Develop plug-ins in unmanaged solutions in dev, source-control the code, then export and deploy as managed solutions; cache reusable reference data outside the plug-in (e.g., in a Function or cache) with a sensible expiry.
Domain 4: Develop Integrations
- Use asynchronous processing (async plug-ins, async flows) for long-running or non-blocking work so it does not delay the user's transaction; use synchronous logic when results must be enforced before save.
- Power Automate cloud flows (automated, instant, scheduled) orchestrate processes across hundreds of connectors with low-code conditional logic, approvals, and event triggers.
- Server-side validation that must apply regardless of client (web, mobile, API, integrations) belongs in a synchronous pre-operation or pre-validation plug-in, because client-side JavaScript can be bypassed.
- Register an asynchronous service endpoint to Azure Service Bus or Event Hub via the event pipeline for durable, decoupled messaging with built-in retry and dead-lettering.
- Use Dataverse webhooks to POST event data to an external HTTPS endpoint synchronously or asynchronously; Service Bus is preferred for high-volume, guaranteed delivery.
- Honor HTTP 429 (Too Many Requests) by reading the Retry-After header and applying exponential backoff with jitter before retrying.
- Replace polling triggers with event-driven Dataverse triggers/webhooks so flows run only on actual changes, reducing API consumption.
- Authenticate external app access with a Microsoft Entra ID app registration using OAuth 2.0 server-to-server (S2S), mapped to a Dataverse application user with least-privilege roles.
- In Power Automate, the 'Invoking user' connection runs Dataverse actions under the triggering user's security context; sharing a flow only grants run permission and does not change the run-as identity.
- Send records in a single bulk request (batch) instead of looping one Web API call per record to stay within service protection API limits.
- Use Azure Functions on the Consumption plan for pay-per-execution integration logic that needs to scale beyond the plug-in sandbox limits.
- Diagnose with the Plug-in Trace Log and ITracingService; combine with Visual Studio remote debugging or the Plug-in Registration Tool profiler for step-through debugging.
- Reference flow outputs with expressions like outputs('Get_account')?['body/accountid']; use Compose and Scope actions to structure and trace flow logic.
- Cache and deduplicate external responses, calling only on real data changes, to minimize cost and throttling against rate-limited APIs.
Domain 5: Extend the User Experience and Platform
- Custom connectors wrap a REST API so Power Apps and Power Automate can consume it; you can define them from an OpenAPI (Swagger) 2.0 JSON definition, a Postman collection, or from scratch.
- Custom connector definitions include actions/triggers, authentication, and policies; configure pagination and define the environment scope in which the connector is available.
- Define connector authentication (e.g., OAuth 2.0) in the connector itself rather than embedding API keys in flows; supported types include No auth, API key, Basic, and OAuth 2.0.
- The Dataverse Web API is OData v4 over REST and is the standard interface for external apps to query and manipulate data using OAuth 2.0 bearer tokens.
- Send the OAuth token in the Authorization header as 'Bearer <token>'; never embed user credentials in requests.
- Application users are non-interactive identities (service principals) for app/integration access; assign them scoped security roles so access is not tied to a person's credentials or license.
- Register the app in Microsoft Entra ID, request only the API permissions the integration actually needs (least privilege), and map it to a Dataverse application user.
- Use the OAuth on-behalf-of flow or a managed identity to call downstream services with a token acquired for the user or service, preserving the correct security context.
- Read secrets from a secured environment variable or an Azure Key Vault reference instead of embedding the secret value in connectors, flows, or code.
- Plug-in assemblies should run in Sandbox (isolation) mode, which restricts network and resource access and is the secure default; Full Trust is only for on-premises and broadens access.
- Virtual tables (virtual entities) surface external data in Dataverse without copying it, but because data stays in the source some features such as full auditing and certain offline scenarios are limited.
- Webhooks and service endpoints publish row created/updated/deleted events from the pipeline to an external consumer for near-real-time integration.
- PCF advanced topics tested include choosing the component type (field vs dataset), debugging with the test harness, and packaging components into a solution for deployment.
- Custom connector advanced topics tested include authentication setup, pagination handling, and the environment scope where the connector can be used.
PL-400 exam tips
- Master the plug-in event pipeline cold: memorize the stages (pre-validation 10, pre-operation 20, post-operation 40), sync vs async, and when each is appropriate. This single topic spans multiple domains.
- Know the pac CLI verbs and key flags by heart (auth create, solution export/import/pack/unpack, --packagetype, --async); the exam tests exact command syntax.
- When a question asks for the lowest-effort solution, follow the ladder: business rule or calculated/rollup column first, then flow, then JavaScript/PCF, then plug-in, then Azure Function - choose the least code that meets the requirement.
- For integration questions, decide async vs sync by whether work is long-running and whether it must block the save; pick Service Bus/webhooks for external messaging and always handle 429 with Retry-After and backoff.
- For security questions, default to OAuth 2.0 with a Microsoft Entra app registration mapped to a least-privilege Dataverse application user, and store secrets in Key Vault via environment variables - never hardcode credentials.
Study guide FAQ
How is the PL-400 scored and what do I need to pass?
Scores are scaled from 1 to 1000 and you need 700 to pass; this is not a raw 70 percent. Questions are weighted, so a few hard items missed will not necessarily fail you. There is no penalty for wrong answers, so answer every question.
When should I use a plug-in versus a Power Automate cloud flow?
Use a synchronous plug-in for server-side logic and validation that must run inside the transaction and apply regardless of client. Use an asynchronous flow (or async plug-in) for longer-running, non-blocking orchestration across connectors. If work exceeds the 2-minute sandbox limit or needs to scale, offload it to an Azure Function.
Do I need to write actual C# and JavaScript code on the exam?
You will not write large programs, but you must read and reason about code snippets: identify the correct Client API call, the right plug-in stage, the proper context property (such as Target or a pre-image), and correct pac CLI commands. Knowing exact method names and parameters matters.
How current is the exam, and does it still reference Azure AD or Common Data Service?
The exam uses current Microsoft branding: Microsoft Entra ID (not Azure AD) and Dataverse (not Common Data Service). It emphasizes the pac CLI, Power Platform Build Tools/GitHub Actions, PCF, custom connectors, and managed-solution ALM. Always review the official skills-measured document for the latest weighting before your exam.