Study guide
5.5 Custom API Messages & Plug-ins That Implement a Custom API
Microsoft Power Platform Developer Associate PL-400
Track your progress as you read
Finished sections get a check mark.
1 Introduction, Exam Overview & Developer Toolchain
0.1 PL-400 Exam Facts 0.2 Audience Profile & Required Developer Skills 0.3 The Power Platform Developer Toolchain 0.4 Extension-Point Map & AI in the Developer Workflow
2 Create a Technical Design
1.1 Analyzing Technical Architecture and Choosing Out-of-the-Box vs. Custom Solutions 1.2 Designing Authentication, Authorization, and Security Architecture 1.3 Deciding Where Business Logic Runs and Choosing the Right Table Type 1.4 Designing Reusable Power Apps Components and Custom Connectors 1.5 Designing Dataverse Code Components, Automations, and Integrations
3 Build Power Platform Solutions
2.1 Managing Power Platform Environments for Development 2.2 Dataverse Security Roles for Code Components, Least Privilege & Troubleshooting Operational Security 2.3 Solutions, Managing Dependencies & Solution Layers 2.4 Environment Variables & Connection References 2.5 Power Platform Pipelines & CI/CD with Power Platform Build Tools
4 Implement Power Apps Improvements
3.1 Complex Power Fx Formulas and Functions 3.2 Building Reusable Canvas Component Libraries 3.3 Invoking Power Automate Cloud Flows from a Canvas App 3.4 Troubleshooting Canvas and Model-Driven Apps with Monitor and Browser Debugging Tools 3.5 Optimizing Canvas and Model-Driven App Performance
5 Extend the User Experience
4.1 The Client API Object Model & JavaScript Form Scripting 4.2 Event Handler Registration & Navigation to Custom Pages via the Client API 4.3 Client Scripting Against the Dataverse Web API; Command Bar & Buttons with Power Fx and JavaScript 4.4 PCF Fundamentals: The Component Manifest & Lifecycle Events 4.5 Implementing PCF Component Interfaces; Device, Utility & Web API Features 4.6 Packaging, Deploying & Consuming a PCF Component
6 Extend the Platform: Dataverse Plug-ins & Custom APIs
5.1 Plug-in Fundamentals & the Event Execution Pipeline Stages 5.2 Execution Context & Implementing Business Logic in Plug-ins 5.3 Pre/Post Images & Organization Service Operations in Plug-ins 5.4 Registering Plug-ins with the Plug-in Registration Tool & Optimizing Plug-in Performance 5.5 Custom API Messages & Plug-ins That Implement a Custom API 5.6 Configuring Dataverse Business Events
7 Extend the Platform: Custom Connectors
6.1 Open API Definitions: Building and Extending a Custom Connector 6.2 Authentication and Policy Templates for Custom Connectors 6.3 Importing Definitions and Creating Connectors for Azure Services 6.4 Azure Functions in Custom Connectors and Data Transformation
8 Extend the Platform: Platform APIs & Azure Functions
7.1 Dataverse Web API Operations & OAuth Authentication 7.2 Organization Service Operations, Concurrency, Transactions & Bulk Operations 7.3 Service Protection API Limits & Retry Policies 7.4 Azure Functions for Long-Running, Scheduled & Event-Driven Workloads 7.5 Authenticating to Power Platform with Managed Identities
9 Extend the Platform: Power Automate Cloud Flows
8.1 Dataverse connector triggers/actions, trigger filters & retry policies 8.2 Complex expressions & flow control with error handling 8.3 Sensitive input/output parameters & Azure Key Vault 8.4 Reusable child flows & Microsoft Entra ID service principals
10 Develop Integrations
9.1 Publishing Dataverse Events: IServiceEndpointNotificationService & the Plug-in Registration Tool 9.2 Registering Service Endpoints: Webhooks, Azure Service Bus & Event Hub 9.3 Data Synchronization with Change Tracking & Alternate Keys 9.4 Upsert-Based Synchronization with the UpsertRequest Message
11 Exam Readiness & Practice
10.1 Cross-Domain "Where Do I Implement This?" Decision Framework 10.2 Exam-Day Strategy, PL-400 Item Styles & Study Plan
5.5 Custom API Messages & Plug-ins That Implement a Custom API
Key Takeaways Explain This Topic AI
A Custom API defines a brand-new, intentionally invoked SDK message with its own name and a strongly typed request/response contract, unlike a plug-in step that reacts to an existing message.
Binding Type controls whether a Custom API is unbound (Global), bound to a single record (Entity), or bound to a collection (Entity Collection); Is Function marks it as a read-only, GET-callable operation versus a data-changing POST action.
The Plugin Type set on the Custom API record automatically registers the implementing plug-in against the new message -- no separate step registration is needed.
The implementing plug-in reads each declared request parameter from InputParameters and writes each declared response property to OutputParameters by name.
Custom APIs are Microsoft's recommended, lightweight replacement for legacy Custom Process Actions, which depend on the workflow engine.
Last updated: July 2026
Every plug-in covered so far has hooked into a message Dataverse already defines -- Create , Update , Delete . A Custom API lets you define a message of your own: a new, strongly-typed operation with its own name, its own request parameters, and its own response, callable through the Web API or the Organization service exactly like a built-in message, without writing a classic workflow-based custom action.
What a Custom API Is
A Custom API is configured declaratively, as data -- a Custom API record plus its Custom API Request Parameter and Custom API Response Property child records -- typically authored in a solution through the maker portal's Custom API designer rather than hand-written SDK metadata calls. Key properties on the Custom API record:
- Property Meaning
- Unique Name The message name callers use to invoke it
Binding Type Global (unbound, not tied to any table), Entity (bound to a single record of a specific table), or Entity Collection (bound to a query or collection of a table)
Bound Entity Logical Name Required when Binding Type is Entity or Entity Collection
Is Function true = a read-only, side-effect-free operation, invoked with HTTP GET , like a query; false = an action that can change data, invoked with HTTP POST
Plugin Type The IPlugin class that implements the API's logic
Allowed Custom Processing Step Type Whether other plugins may additionally register pre/post-operation steps around this custom message (None, Async only, or Sync and Async)
Request and response parameters each declare a Name and a Type drawn from the standard SDK type set -- String , Integer , Boolean , DateTime , Decimal , Float , Money , Entity , EntityCollection , EntityReference , Picklist , StringArray , Guid -- giving the message a real, discoverable contract rather than a loosely typed bag of values.
Calling a Custom API
Once published, a Custom API is callable exactly like a built-in message:
Web API: POST https://org.crm.dynamics.com/api/data/v9.2/new_CalculateShippingCost for an unbound (Global) action, or .../accounts(id)/Microsoft.Dynamics.CRM.new_ApproveAccount for a bound one. A function, bound or unbound, is called with GET instead.
Organization service: build an OrganizationRequest("new_CalculateShippingCost") , populate its Parameters collection with the declared request parameters, and call service.Execute(request) -- the same pattern used for any SDK message.
The Implementing Plug-in
Unlike a normal step, you don't separately register the plugin type against the message in the Plug-in Registration Tool -- publishing the Custom API record with its Plugin Type set does that automatically. Inside the plugin, the pattern mirrors any other Execute method, but the developer reads each declared request parameter from InputParameters by name and writes each declared response property to OutputParameters by name: public void Execute(IServiceProvider serviceProvider)
- {
- IPluginExecutionContext context =
- (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
- var accountId = (Guid)context.InputParameters["AccountId"];
- var orderTotal = ((Money)context.InputParameters["OrderTotal"]).Value;
decimal shippingCost = CalculateShipping(orderTotal);
- context.OutputParameters["ShippingCost"] = new Money(shippingCost);
- }
Because the request and response shape is declared on the Custom API record itself, both the Web API's $metadata and SDK tooling can describe the operation's contract to callers automatically -- a JavaScript form script (4.3) or a Power Automate flow can discover and call it like any native message.
Custom API vs. Custom Process Action vs. a Plain Plug-in Step
Two comparisons the exam likes to draw:
Custom API vs. classic Custom Process Action. A Custom Process Action, sometimes called a "classic Action," is defined through the legacy process/workflow designer, stored as a workflow definition, and executed through the workflow engine -- heavier weight, and largely a legacy pattern Microsoft has superseded. A Custom API is code-first, lightweight, natively exposed through the Web API without a workflow-engine dependency, and is the recommended approach for new development.
Custom API vs. a plug-in on a standard message. A plug-in step registered on Update subscribes to something that already happens as a side effect of ordinary data entry -- it can't be invoked deliberately on its own. A Custom API instead creates a brand-new, intentionally invoked operation with its own name and contract: use one whenever the requirement is "let a caller explicitly ask the platform to do X," such as approve a record, calculate a value, or kick off a process, rather than "react whenever a record changes." Design-wise, this is the same distinction Domain 1's technical-design guidance draws around code components (1.5): a Custom API is the modern building block for exposing custom server-side logic as its own first-class, callable operation.