
Another journey on how to create a Power Automate Custom Connector with .NET API 8. Last week, we created a .NET API Project that implements the API Key for the Authorization process. Today, we will add more features including adding monitoring logs using Azure Application Insight and how to create an action where we can implement the retry function.
Add Azure Application Insight
If you already deployed your API into Azure App Service > you can go to “Monitoring” > Application Insights > you can click “Enable” > “Create new resource” > set the Name, Location, and also the Log Analytics Workspace > click “Apply“:

Create Azure Application Insight
If you open the App Service > Settings > Environment Variables, the system will generate the settings necessary for Azure Application Insight.
.NET API
From last week’s implementation, I learned that I was wrong about how to provide “Request-Response” information to Power Automate Custom Connector. The best way is still using swagger.json information which I corrected on today’s implementation. But, first, we need to add below NuGet package:
Microsoft.ApplicationInsights.AspNetCore
Once installed, you can create a Folder named “Logging” and add the below class:
123456789101112131415161718 | using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility; namespace PowerAutomateCustomConnector.Logging; public class CustomHeaderTelemetryInitializer(IHttpContextAccessor httpContextAccessor) : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { if (telemetry is not RequestTelemetry requestTelemetry) return ; // Add custom headers to the request telemetry var headers = string .Join( "," , httpContextAccessor.HttpContext?.Request.Headers.Select(x => $ "{x.Key}: {x.Value}" ) ?? Array.Empty< string >()); requestTelemetry.Properties[ "HttpHeaders" ] = headers; requestTelemetry.Properties[ "HttpBody" ] = httpContextAccessor.HttpContext?.Request.Body?.ToString(); } } |
The purpose of the above code is to add more information to the Request table (inside the CustomDimensions). You can skip this part as this is not mandatory. The idea of this is to add more information if you need to use it later on for analysis purposes.
about:blank
Next, here are the changes on the Program.cs. Here I’m still using minimal API. But, for sure. If the requirements become more and more complex, we can split the implementation.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 | using Microsoft.ApplicationInsights.Extensibility; using Microsoft.OpenApi.Models; using PowerAutomateCustomConnector.Authentication; using PowerAutomateCustomConnector.Logging; var builder = WebApplication.CreateBuilder(args); // Add services to the container. // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.AddSecurityDefinition( "ApiKey" , new OpenApiSecurityScheme { Type = SecuritySchemeType.ApiKey, Name = "x-api-key" , In = ParameterLocation.Header }); c.AddSecurityRequirement( new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "ApiKey" } }, [] } }); }); builder.Services.AddAuthorization(); builder.Services.AddAuthentication(); builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); builder.Services.AddSingleton<ITelemetryInitializer, CustomHeaderTelemetryInitializer>(); builder.Services.AddApplicationInsightsTelemetry(); var app = builder.Build(); app.UseSwagger(c => { c.SerializeAsV2 = true ; c.PreSerializeFilters.Add((swagger, httpReq) => swagger.Servers = new List<OpenApiServer>( new OpenApiServer[] { new () { Url = $ "{httpReq.Scheme}://{httpReq.Host.Value}" } })); }); app.UseSwaggerUI(); app.UseAuthorization(); app.UseAuthentication(); app.UseMiddleware<ApiAuthenticationMiddleware>(); app.UseHttpsRedirection(); app.MapPost( "/orderAsc" , ( string [] stringArray) => { if (stringArray.Contains( "Error" )) { return Results.Problem( "Error" , statusCode: StatusCodes.Status429TooManyRequests); } var result = stringArray.OrderBy(e=> e).ToArray(); return Results.Ok(result); }) .Produces(StatusCodes.Status200OK) .Produces(StatusCodes.Status429TooManyRequests) .WithName( "OrderAsc" ); app.Run(); |
Let’s break down the changes for today’s implementation:
- For lines 11-23, this is the mandatory setting for Swagger so we can enable API Key Authentication via Swagger UI. Once you add this and open the URL/swagger, you can see the below Authorize button and you can key in the x-api-key also for testing directly via Swagger UI:

- For lines 28 – 29, we added these 2 lines to supply the information needed CustomHeaderTelemetryInitializer.cs.
- For line 30, we enabled the Application Insight (it will automatically use the settings in App Service > Settings > Environment Variables) to our API.
- For lines 34-42, we force the Swagger to use V2 and add the “Host” parameter as this is mandatory when we want to update the Custom Connector.
- For lines 51-63, we changed the API implementation to a simple function to order an array of strings. If there is a string with the value of “Error“, it will throw an HTTP error code of 429 (Too Many Requests). With the return of these error codes (408, 429, and 5xx), we can ask Power Automate to run the retry function with the predefined policy (which will be explained later on).
With these changes, you can deploy to your App Service!
Update Custom Connector and Power Automate Testing
Once you deploy the changes into your App Service, you can go to YOUR-URL/swagger > there you can click the swagger.json:

swagger.json file
You can copy the content of the above file > go to your Custom Connector > click the “Swagger editor” > then click in the editor > Ctrl + All to select all existing content >paste the swagger.json content:

Change the Custom Connector definition
Once you paste the content, it will be asking you if you want to replace the content as yaml:

Confirmation to paste the JSON as YAML
If you go to the “Definition“, then you can see that the Response now contains “200 – Success” and also “429 – Too Many Requests“:

Update Response API
Last, for the demo, I created the below flow to invoke the “Retry” mechanism:

Create Flow with “Error” string
Next, you can go to Advance Options (… button on the top left side of the action) of the Custom Connector > Settings > On “Retry Policy” we can set the Type as “Fixed Interval“, Count as 3, and Interval as PT20S which means it will keep retrying the process every 20 seconds (until 3 times). Once done, you can run the Test and we can verify it as well from the Azure Application Insights:

Retry function + Azure Application Insight Logs
Here is the result if the Custom Connector is successfully run:

Demo success
Hope you learn something today! Happy CRM-ing! 😎
About the Author

Temmy Wahyu Raharjo, MVP
Dynamics CRM CE Technical Consultant | Power Platform | Blogger | MVP Business Applications | Loves the concept of Test Driven Development | Certified MCP | Certified Scrum Master
Reference:
Wahyu, T (2025). Power Automate Custom Connector – Implement Retry Function, Azure Application Insights. Available at: Power Automate Custom Connector – Implement Retry Function, Azure Application Insights – Temmy Wahyu Raharjo [Accessed: 15th January 2025].