Wicked Smart Data
LearnArticlesAbout
Sign InSign Up
LearnArticlesAboutContact
Sign InSign Up
Wicked Smart Data

The go-to platform for professionals who want to master data, automation, and AI — from Excel fundamentals to cutting-edge machine learning.

Platform

  • Learning Paths
  • Articles
  • About
  • Contact

Connect

  • Contact Us
  • RSS Feed

© 2026 Wicked Smart Data. All rights reserved.

Privacy PolicyTerms of Service
All Articles
Advanced Power Automate: Custom Connectors and HTTP Actions for Production Integration

Advanced Power Automate: Custom Connectors and HTTP Actions for Production Integration

Power Automate⚡ Practitioner12 min readApr 6, 2026Updated Apr 6, 2026
Table of Contents
  • Prerequisites
  • Understanding HTTP Actions in Power Automate
  • Handling Authentication Patterns
  • Error Handling and Retry Logic
  • Building Custom Connectors
  • Advanced Custom Connector Features
  • Testing and Validation
  • Hands-On Exercise: Building a Slack Notification Connector
  • Common Mistakes & Troubleshooting
  • Performance and Production Considerations
  • Summary & Next Steps

You're building a financial reconciliation flow when you hit a wall. The accounting system your company uses doesn't have a built-in Power Automate connector, but it does have a REST API. Your flow needs to automatically pull transaction data every night, validate it against your CRM records, and push discrepancies to a tracking system. Standard connectors won't cut it—you need direct API control.

This is where Power Automate's HTTP actions and custom connectors become essential tools. While pre-built connectors handle common scenarios, real-world automation often requires direct API integration. HTTP actions give you the flexibility to connect to any REST API, while custom connectors let you package that functionality for reuse and sharing across your organization.

What you'll learn:

  • Build robust HTTP requests with authentication, headers, and error handling
  • Create and deploy custom connectors for internal and external APIs
  • Handle complex authentication scenarios including OAuth 2.0 and API keys
  • Implement retry logic and proper error handling for production flows
  • Test and troubleshoot API integrations systematically

Prerequisites

You should be comfortable building flows with standard connectors, understand basic HTTP concepts (GET, POST, status codes), and have experience with JSON data manipulation in Power Automate. Familiarity with REST APIs is helpful but not required.

Understanding HTTP Actions in Power Automate

Power Automate's HTTP connector provides three main actions: HTTP, HTTP with Azure AD, and Webhook. The standard HTTP action handles most scenarios, while HTTP with Azure AD simplifies authentication for Azure-protected resources.

Let's start with a practical example. You need to integrate with a vendor's invoice API that requires API key authentication and returns paginated results. Here's how to structure this systematically:

{
  "method": "GET",
  "uri": "https://api.vendorname.com/v2/invoices",
  "headers": {
    "Authorization": "Bearer @{parameters('API_Key')}",
    "Content-Type": "application/json",
    "Accept": "application/json",
    "User-Agent": "PowerAutomate-Integration/1.0"
  },
  "queries": {
    "limit": "50",
    "offset": "@{mul(variables('pageNumber'), 50)}",
    "status": "pending",
    "created_after": "@{formatDateTime(addDays(utcNow(), -7), 'yyyy-MM-dd')}"
  }
}

The key elements here are authentication headers, proper content-type specification, and dynamic query parameters. The User-Agent header identifies your integration to the API provider—many require this for support purposes.

For POST requests with data, structure your request body carefully:

{
  "method": "POST",
  "uri": "https://api.vendorname.com/v2/invoices/@{variables('invoiceId')}/approve",
  "headers": {
    "Authorization": "Bearer @{parameters('API_Key')}",
    "Content-Type": "application/json"
  },
  "body": {
    "approved_by": "@{triggerBody()?['approver_email']}",
    "approved_at": "@{utcNow()}",
    "notes": "@{triggerBody()?['approval_notes']}",
    "internal_reference": "@{guid()}"
  }
}

Notice how we're using Power Automate expressions to populate dynamic values. The guid() function generates unique tracking IDs, while triggerBody() pulls data from the flow trigger.

Handling Authentication Patterns

Different APIs require different authentication approaches. API keys are straightforward, but OAuth 2.0 flows require more sophisticated handling.

For OAuth 2.0 authentication, you'll often need a two-step process. First, obtain an access token:

{
  "method": "POST",
  "uri": "https://oauth.provider.com/token",
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "body": "grant_type=client_credentials&client_id=@{parameters('ClientId')}&client_secret=@{parameters('ClientSecret')}&scope=invoice:read invoice:write"
}

Then use the returned token in subsequent requests:

{
  "method": "GET",
  "uri": "https://api.provider.com/data",
  "headers": {
    "Authorization": "Bearer @{body('HTTP_Get_Token')?['access_token']}"
  }
}

Security tip: Always store sensitive credentials like API keys and client secrets as flow parameters or environment variables, never hard-code them in the flow definition.

Error Handling and Retry Logic

Production integrations must handle failures gracefully. Power Automate provides built-in retry policies, but you need to configure them appropriately for your scenario.

Configure retry settings on your HTTP action:

{
  "retryPolicy": {
    "type": "exponential",
    "count": 4,
    "interval": "PT20S",
    "maximumInterval": "PT1H",
    "minimumInterval": "PT5S"
  }
}

This implements exponential backoff: 20 seconds, then 40, then 80, then 160 seconds between retries. The maximum interval prevents excessive delays.

For more sophisticated error handling, wrap your HTTP actions in try-catch blocks using parallel branches:

{
  "actions": {
    "Try_HTTP_Request": {
      "type": "Scope",
      "actions": {
        "HTTP_API_Call": {
          // your HTTP action here
        }
      }
    },
    "Catch_Errors": {
      "type": "Scope",
      "actions": {
        "Handle_API_Error": {
          "type": "Switch",
          "expression": "@outputs('HTTP_API_Call')['statusCode']",
          "cases": {
            "429": {
              // Rate limit - wait and retry
            },
            "401": {
              // Authentication failed - refresh token
            },
            "500": {
              // Server error - log and alert
            }
          }
        }
      },
      "runAfter": {
        "Try_HTTP_Request": ["Failed", "TimedOut"]
      }
    }
  }
}

Building Custom Connectors

When you're repeatedly using the same API across multiple flows, or when you need to share API integration with team members, custom connectors provide a cleaner solution. Custom connectors wrap HTTP operations into reusable, configurable actions.

Let's build a custom connector for a hypothetical expense management API. Start in the Power Automate portal by navigating to Data > Custom connectors > New custom connector > Create from blank.

Define the connector's basic information:

  • Name: ExpenseTracker API
  • Description: Connector for ExpenseTracker expense management system
  • Host: api.expensetracker.com
  • Base URL: /v3/

In the Security section, configure authentication. For our example, we'll use API Key authentication:

  • Authentication type: API Key
  • Parameter label: API Key
  • Parameter name: X-API-Key
  • Parameter location: Header

Now define your connector's actions. Each action corresponds to an API endpoint. For a "Get Expenses" action:

General information:

  • Summary: Get expense reports
  • Description: Retrieves expense reports with optional filtering
  • Operation ID: GetExpenses
  • Visibility: important

Request configuration:

  • URL: /expenses
  • Method: GET

Parameters:

  • employee_id (query, string, optional): Employee ID to filter by
  • start_date (query, string, optional): Start date (YYYY-MM-DD format)
  • end_date (query, string, optional): End date (YYYY-MM-DD format)
  • status (query, string, optional): Status filter (submitted, approved, paid)

For the response, provide a sample JSON response so Power Automate can understand the data structure:

{
  "expenses": [
    {
      "id": "exp_123456",
      "employee_id": "emp_789",
      "amount": 125.50,
      "currency": "USD",
      "category": "Travel",
      "description": "Client meeting lunch",
      "receipt_url": "https://receipts.expensetracker.com/receipt_123456.pdf",
      "submitted_date": "2024-01-15T10:30:00Z",
      "status": "submitted"
    }
  ],
  "total_count": 1,
  "page": 1,
  "per_page": 50
}

Create a "Submit Expense" action for POST operations:

Request configuration:

  • URL: /expenses
  • Method: POST
  • Body: Raw JSON with the expense data structure

Request body schema:

{
  "type": "object",
  "properties": {
    "employee_id": {
      "type": "string",
      "description": "Employee ID"
    },
    "amount": {
      "type": "number",
      "description": "Expense amount"
    },
    "currency": {
      "type": "string",
      "description": "Currency code (USD, EUR, etc.)"
    },
    "category": {
      "type": "string",
      "description": "Expense category"
    },
    "description": {
      "type": "string",
      "description": "Expense description"
    },
    "receipt_data": {
      "type": "string",
      "description": "Base64 encoded receipt image"
    }
  },
  "required": ["employee_id", "amount", "currency", "category"]
}

Advanced Custom Connector Features

Custom connectors support sophisticated features for production use. Policy templates let you transform requests and responses without modifying the underlying API.

Add a policy template to automatically handle pagination:

<policies>
  <inbound>
    <set-query-parameter name="page" value="@{policy.request.query['page'] ?? '1'}" />
    <set-query-parameter name="per_page" value="@{policy.request.query['per_page'] ?? '50'}" />
  </inbound>
  <outbound>
    <set-body>
      @{
        var response = policy.response.body;
        if (response != null && response.data != null) {
          return Json.Stringify(new {
            items = response.data,
            nextLink = response.pagination?.next_page != null ? 
              "https://api.expensetracker.com/v3/expenses?page=" + response.pagination.next_page : null
          });
        }
        return policy.response.body;
      }
    </set-body>
  </outbound>
</policies>

This policy transforms the API's pagination format into Power Automate's expected format, making it easier to use in flows.

For OAuth 2.0 APIs, configure the security settings with proper scopes and redirect URLs:

OAuth 2.0 Configuration:

  • Identity Provider: Generic OAuth 2
  • Client ID: Your registered application ID
  • Client Secret: Your application secret
  • Authorization URL: https://oauth.provider.com/authorize
  • Token URL: https://oauth.provider.com/token
  • Refresh URL: https://oauth.provider.com/token
  • Scopes: expense:read expense:write profile:read

The connector handles the OAuth flow automatically, presenting users with an authentication dialog when they first use the connector.

Testing and Validation

Before deploying custom connectors, thoroughly test each operation. Use the built-in test functionality in the custom connector editor, but also create dedicated test flows.

Create a comprehensive test flow that exercises all connector operations:

  1. Authentication Test: Verify the connector authenticates successfully
  2. CRUD Operations: Test Create, Read, Update, Delete operations
  3. Error Scenarios: Test with invalid parameters, authentication failures, and rate limits
  4. Edge Cases: Test with empty responses, large datasets, and special characters

Document expected behavior for each test case:

{
  "test_cases": [
    {
      "name": "Get Expenses - Valid Request",
      "action": "GetExpenses",
      "parameters": {
        "employee_id": "emp_123",
        "start_date": "2024-01-01"
      },
      "expected_result": "Success with expense array"
    },
    {
      "name": "Get Expenses - No Results",
      "action": "GetExpenses", 
      "parameters": {
        "employee_id": "emp_999"
      },
      "expected_result": "Success with empty array"
    },
    {
      "name": "Submit Expense - Invalid Amount",
      "action": "SubmitExpense",
      "parameters": {
        "amount": -50.00
      },
      "expected_result": "400 Bad Request error"
    }
  ]
}

Hands-On Exercise: Building a Slack Notification Connector

Let's build a practical custom connector that sends rich notifications to Slack channels. This exercise demonstrates real-world connector development from start to finish.

Step 1: Slack App Setup

First, create a Slack app in your workspace:

  1. Go to api.slack.com/apps and click "Create New App"
  2. Choose "From scratch" and provide app name and workspace
  3. Navigate to "OAuth & Permissions" in the sidebar
  4. Add these Bot Token Scopes: chat:write, files:write, channels:read
  5. Install the app to your workspace and copy the Bot User OAuth Token

Step 2: Create the Custom Connector

In Power Automate, create a new custom connector:

General Tab:

  • Name: Slack Rich Notifications
  • Description: Send rich notifications and files to Slack channels
  • Host: slack.com
  • Base URL: /api/

Security Tab:

  • Authentication Type: API Key
  • Parameter Label: Bot Token
  • Parameter Name: Authorization
  • Parameter Location: Header
  • Add "Bearer " prefix to the parameter value

Definition Tab - Send Message Action:

Create an action called "Send Rich Message":

  • Summary: Send a rich message to Slack channel
  • Operation ID: SendRichMessage
  • URL: /chat.postMessage
  • Method: POST

Parameters:

  • channel (string, required): Channel ID or name
  • text (string, required): Message text
  • username (string, optional): Bot username override
  • icon_emoji (string, optional): Bot icon emoji
  • attachments (array, optional): Rich message attachments

Request Body Schema:

{
  "type": "object",
  "properties": {
    "channel": {"type": "string"},
    "text": {"type": "string"},
    "username": {"type": "string"},
    "icon_emoji": {"type": "string"},
    "attachments": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "color": {"type": "string"},
          "title": {"type": "string"},
          "text": {"type": "string"},
          "fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {"type": "string"},
                "value": {"type": "string"},
                "short": {"type": "boolean"}
              }
            }
          }
        }
      }
    }
  },
  "required": ["channel", "text"]
}

Step 3: Add File Upload Action

Create a second action for uploading files:

  • Summary: Upload file to Slack channel
  • Operation ID: UploadFile
  • URL: /files.upload
  • Method: POST

Parameters:

  • channels (string, required): Channel ID
  • filename (string, required): File name
  • content (string, required): Base64 encoded file content
  • title (string, optional): File title
  • initial_comment (string, optional): Initial comment

Step 4: Test the Connector

Test both actions with realistic data:

Rich Message Test:

{
  "channel": "#general",
  "text": "Expense Report Alert",
  "username": "ExpenseBot",
  "icon_emoji": ":money_with_wings:",
  "attachments": [
    {
      "color": "warning",
      "title": "New Expense Report Pending",
      "text": "Employee John Doe submitted an expense report requiring approval",
      "fields": [
        {
          "title": "Amount",
          "value": "$1,250.00",
          "short": true
        },
        {
          "title": "Category", 
          "value": "Travel",
          "short": true
        },
        {
          "title": "Submitted",
          "value": "2024-01-15 10:30 AM",
          "short": false
        }
      ]
    }
  ]
}

Step 5: Create a Production Flow

Build a flow that uses your custom connector in a realistic scenario:

  1. Trigger: When an item is created in SharePoint (expense reports list)
  2. Get file content: Retrieve any attached receipts
  3. Slack Rich Notifications - Send Rich Message: Notify the approval channel
  4. Condition: If receipts are attached
  5. Slack Rich Notifications - Upload File: Upload receipt images

This demonstrates how custom connectors integrate seamlessly with other Power Automate actions.

Common Mistakes & Troubleshooting

Authentication Issues

The most common problem is authentication configuration. Always test authentication separately before building complex flows. For API keys, verify the header name and format requirements—some APIs expect "Authorization: Bearer token", others use custom headers like "X-API-Key: token".

JSON Schema Mismatches

When APIs return unexpected data structures, flows fail with schema validation errors. Build robust flows that handle varying response formats:

{
  "condition": {
    "expression": "@and(not(empty(body('HTTP_Action'))), contains(body('HTTP_Action'), 'data'))",
    "then": {
      "processData": "@body('HTTP_Action')['data']"
    },
    "else": {
      "processData": "@body('HTTP_Action')"
    }
  }
}

Rate Limiting

APIs often implement rate limits that cause 429 errors. Implement exponential backoff and respect rate limit headers:

{
  "retryAfter": "@if(contains(outputs('HTTP_Action')['headers'], 'Retry-After'), outputs('HTTP_Action')['headers']['Retry-After'], '60')"
}

Custom Connector Deployment

Custom connectors created in one environment don't automatically appear in others. Export your connector definition and import it into each target environment. For organization-wide deployment, work with your Power Platform administrator to deploy as a certified connector.

Testing in Different Environments

APIs behave differently in development versus production environments. Test your connectors against production-like data volumes and real API rate limits, not just development sandbox APIs.

Performance and Production Considerations

When building flows that make multiple HTTP requests, consider the performance implications. Sequential API calls can create long-running flows that may timeout. Instead, use parallel branches for independent operations:

{
  "parallel_branches": {
    "get_customer_data": {
      "actions": ["HTTP_Get_Customer"]
    },
    "get_order_history": {
      "actions": ["HTTP_Get_Orders"]  
    },
    "get_payment_methods": {
      "actions": ["HTTP_Get_Payments"]
    }
  }
}

For bulk operations, implement batching when the API supports it. Instead of making 100 individual requests, make 10 requests with 10 items each:

{
  "batch_size": 10,
  "batched_items": "@chunk(variables('all_items'), 10)",
  "process_batch": {
    "type": "Foreach",
    "foreach": "@variables('batched_items')",
    "actions": {
      "HTTP_Batch_Process": {
        "method": "POST",
        "body": "@items('process_batch')"
      }
    }
  }
}

Monitor your flows' performance using the Power Automate analytics dashboard. Look for patterns in failure rates and execution times that might indicate API reliability issues or rate limiting problems.

Summary & Next Steps

HTTP actions and custom connectors unlock Power Automate's full integration potential. You've learned to build robust API integrations with proper authentication, error handling, and retry logic. Custom connectors let you package these integrations for reuse and sharing across your organization.

The key principles to remember:

  • Always implement proper error handling and retry logic
  • Use secure credential storage for API keys and secrets
  • Test thoroughly across different scenarios and data volumes
  • Document your connectors for team members and future maintenance

Next steps for advancement:

  • Explore Power Platform governance for custom connector lifecycle management
  • Learn about connector certification for organization-wide deployment
  • Study advanced policy templates for request/response transformation
  • Practice with different authentication patterns (SAML, certificate-based auth)
  • Build connectors for your organization's internal APIs

Custom connectors become especially powerful when combined with Power Platform's other components. Consider how your connectors might integrate with Power Apps for user interfaces, or Power BI for data visualization of API-sourced data.

Learning Path: Flow Automation Basics

Previous

Power Automate Best Practices: Master Flow Naming, Testing, and Monitoring

Related Articles

Power Automate🌱 Foundation

Power Automate Best Practices: Master Flow Naming, Testing, and Monitoring

13 min
Power Automate🔥 Expert

Building Approval Workflows with Power Automate

21 min
Power Automate⚡ Practitioner

Desktop Flows: Automate Legacy Applications with RPA in Power Automate

25 min

On this page

  • Prerequisites
  • Understanding HTTP Actions in Power Automate
  • Handling Authentication Patterns
  • Error Handling and Retry Logic
  • Building Custom Connectors
  • Advanced Custom Connector Features
  • Testing and Validation
  • Hands-On Exercise: Building a Slack Notification Connector
  • Common Mistakes & Troubleshooting
  • Performance and Production Considerations
  • Summary & Next Steps