Custom APIs & Business Events
Create your own Dataverse endpoints that any app, flow, or external system can call. Learn custom API messages, custom API plug-ins, and business events for real-time event publishing.
Creating your own Dataverse operations
Think of custom APIs as adding new buttons to a universal remote control.
Dataverse comes with built-in operations: Create, Update, Delete, Retrieve. These are like the standard buttons on a TV remote — power, volume, channel. But what if you need a “Calculate Shipping” button or a “Validate Insurance” button? You create a custom API.
A custom API is a new operation you define on Dataverse. You name it, declare what inputs it accepts and what outputs it returns, and wire it to a plug-in that does the actual work. Then anyone — apps, flows, external systems — can call your API just like they call the built-in Create or Update.
Business events are the flip side: instead of something calling IN to Dataverse, business events let Dataverse push events OUT to other systems when something important happens.
Custom API anatomy
A custom API consists of three parts:
- The API definition — name, binding type, request parameters, response properties
- Request parameters — typed inputs the caller sends
- Response properties — typed outputs the API returns
Creating a custom API
| Setting | What It Controls | Example |
|---|---|---|
| Unique Name | API identifier (used in SDK/Web API calls) | nova_CalculateShipping |
| Display Name | Human-readable name | Calculate Shipping Cost |
| Binding Type | Global (no entity) or Entity-bound | Global — not tied to a specific table |
| Is Function | GET (read-only) or POST (action) | No (POST — it performs a calculation) |
| Is Private | Hidden from external callers | No — ISVs and external systems can call it |
| Allowed Custom Processing Step Type | Sync only, Async only, or Both | Sync only (caller waits for result) |
| Plugin Type | The plug-in that implements the logic | NovaSoft.ShippingCalculator |
Defining parameters and response
Request Parameters:
- Weight (Decimal, required)
- DestinationCode (String, required)
- Priority (Integer, optional)
Response Properties:
- Cost (Decimal)
- EstimatedDays (Integer)
- TrackingPrefix (String)
Implementing the plug-in
public class CalculateShipping : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// Read custom API request parameters
decimal weight = (decimal)context.InputParameters["Weight"];
string destination = (string)context.InputParameters["DestinationCode"];
int priority = context.InputParameters.Contains("Priority")
? (int)context.InputParameters["Priority"] : 1;
// Business logic
decimal baseCost = weight * 2.5m;
decimal priorityMultiplier = priority == 1 ? 1.0m : priority == 2 ? 1.5m : 2.0m;
decimal cost = baseCost * priorityMultiplier;
int estimatedDays = priority == 3 ? 1 : priority == 2 ? 3 : 5;
// Set custom API response properties
context.OutputParameters["Cost"] = cost;
context.OutputParameters["EstimatedDays"] = estimatedDays;
context.OutputParameters["TrackingPrefix"] = "TRK-" + destination;
}
}
Calling the custom API
From the Web API (any HTTP client):
POST /api/data/v9.2/nova_CalculateShipping
Content-Type: application/json
{
"Weight": 25.5,
"DestinationCode": "NZ-AKL",
"Priority": 2
}
From a cloud flow: Use the “Perform an unbound action” Dataverse connector action.
From C# SDK: service.Execute(new OrganizationRequest("nova_CalculateShipping") { ... });
Business events
Business events let Dataverse broadcast events to external systems when specific operations occur.
How they work
- Define a business event on a table (e.g., “Order Approved” on the Order table)
- Configure the trigger — which message and stage fires the event
- Subscribe external systems — Azure Service Bus, Event Hub, webhooks
- Events publish automatically when the trigger condition is met
Business events vs plug-ins
| Feature | Business Event | Plug-in |
|---|---|---|
| Purpose | Notify external systems | Execute custom logic in Dataverse |
| Direction | Outbound (Dataverse → external) | Internal (within Dataverse pipeline) |
| Custom code | No code needed for basic events | C# code required |
| Subscribers | Service Bus, Event Hub, webhooks | N/A — plug-in runs internally |
| Solution-aware | Yes | Yes |
| Use when | External systems need to react to Dataverse changes | You need to validate, enrich, or process data within Dataverse |
Elena needs to create an operation that accepts an employee ID and returns their accrued leave balance. The operation must be callable from canvas apps, cloud flows, and an external HR system via REST API. What should she build?
🎬 Video coming soon
Next up: Custom Connectors: OpenAPI & Authentication — wrapping external APIs for Power Platform consumption.