This guide documents how to set up and configure API connections for testing Connectors SDK generated code.
- Azure CLI installed and logged in (
az login) - Access to an Azure subscription with Logic Apps connections
- A Logic Apps Standard app (for creating connections with runtime URLs)
Use the setup script to automate the entire process:
.\scripts\Setup-Connection.ps1 `
-SubscriptionId "<your-subscription-id>" `
-ResourceGroup "<your-resource-group>" `
-ConnectionName "<your-connection-name>"For Office365 connections, use a different test path:
.\scripts\Setup-Connection.ps1 `
-SubscriptionId "<your-subscription-id>" `
-ResourceGroup "<your-resource-group>" `
-ConnectionName "office365" `
-TestPath "/Categories"There are two ways to create connections, depending on whether you use the Connector Namespace:
Connector Namespace connections are required for connector triggers (Connector Namespace manages the polling infrastructure). They also work for actions.
$subscriptionId = "<your-subscription-id>"
$resourceGroup = "<your-resource-group>"
$namespaceName = "<your-namespace-name>"
$location = "<azure-region>" # e.g., "brazilsouth"
az rest --method PUT `
--uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connectorGateways/$namespaceName?api-version=2026-05-01-preview" `
--body "{`"location`":`"$location`",`"properties`":{},`"identity`":{`"type`":`"SystemAssigned`"}}"$connectorName = "office365" # API connector name
$connectionName = "office365-test"
az rest --method PUT `
--uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connectorGateways/$namespaceName/connections/$connectionName?api-version=2026-05-01-preview" `
--body "{`"properties`":{`"connectorName`":`"$connectorName`"}}"The connection is created in an unauthenticated state. You must complete OAuth consent.
- Open the Connector Namespace Manager Portal
- Run the command shown on the portal to get an ARM token, paste it, and save
- Select your Connector Namespace — the connections will appear
- Click Authorize on the connection requiring consent
- Complete the OAuth flow. Status changes from
ErrortoConnected.
Note: The DF consent endpoint (
/login) returns 500. Only the portal UI consent flow works reliably.
After OAuth consent, the connection runtime URL is available:
- In the Connector Namespace Manager Portal: select the connection → copy the runtime URL
- Via ARM API:
$result = az rest --method GET `
--uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connectorGateways/$namespaceName/connections/$connectionName?api-version=2026-05-01-preview" `
-o json | ConvertFrom-Json
$result.properties.connectionRuntimeUrlGrant the Function App's managed identity access to use the connection:
$msiObjectId = "<function-app-msi-object-id>"
$tenantId = "<aad-tenant-id>"
$policyName = "functionapp-msi"
az rest --method PUT `
--uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connectorGateways/$namespaceName/connections/$connectionName/accessPolicies/$policyName?api-version=2026-05-01-preview" `
--body "{`"properties`":{`"principal`":{`"type`":`"ActiveDirectory`",`"identity`":{`"objectId`":`"$msiObjectId`",`"tenantId`":`"$tenantId`"}}}}" `
--headers "Content-Type=application/json"Important: The
Content-Type: application/jsonheader is required — omitting it returns HTTP 415.
The same connection (and access policy) is used for both triggers and actions.
Standalone connections work for actions but do not support Connector Namespace triggers.
If you prefer standalone connections, follow these steps.
The easiest way is through the Azure Portal:
- Open your Logic Apps Standard app
- Go to Connections > Add connection
- Select the connector (e.g., SharePoint, Office365)
- Complete OAuth authorization
Alternatively, connections can be created via ARM templates or CLI.
# Replace with your values
$subscriptionId = "<your-subscription-id>"
$resourceGroup = "<your-resource-group>"
$connectionName = "<your-connection-name>"
# Get the runtime URL
az resource show `
--ids "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connections/$connectionName" `
--query "properties.connectionRuntimeUrl" `
-o tsvExpected output format:
https://{instance}.{region}.common.logic-{environment}.azure-apihub.net/apim/{connector}/{connection-id}
Note: If the runtime URL is empty, the connection was created as a classic ARM connection, not through a Logic Apps Standard app. You'll need to create a new connection from a Logic Apps Standard app.
az resource show `
--ids "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connections/$connectionName" `
--query "properties.statuses[0]" `
-o jsonExpected for healthy connection:
{ "status": "Connected" }If you see invalid_grant or Unauthorized, the connection needs to be re-authorized (see Step 4).
If the OAuth token has expired:
# Create consent body file
$consentBody = @{
parameters = @(
@{
redirectUrl = "https://portal.azure.com"
parameterName = "token"
}
)
} | ConvertTo-Json -Depth 3
$consentBody | Out-File "$env:TEMP\consent-body.json" -Encoding UTF8
# Get consent link
az resource invoke-action `
--ids "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connections/$connectionName" `
--action "listConsentLinks" `
--api-version "2018-07-01-preview" `
--request-body "@$env:TEMP\consent-body.json" `
-o jsonOpen the returned link URL in your browser to complete OAuth authorization.
The Connectors SDK defaults to ManagedIdentityCredential which authenticates as the app's system-assigned managed identity. For local development, pass AzureCliCredential explicitly. Your Azure CLI identity (az login) must have an access policy on the connection.
# Get your user object ID
$userObjectId = az ad signed-in-user show --query "id" -o tsv
# Get your tenant ID
$tenantId = az account show --query "tenantId" -o tsv$policyName = "local-dev" # Any unique name
# Create access policy body
$accessPolicyBody = @{
properties = @{
principal = @{
type = "ActiveDirectory"
identity = @{
objectId = $userObjectId
tenantId = $tenantId
}
}
}
} | ConvertTo-Json -Depth 5
$accessPolicyBody | Out-File "$env:TEMP\access-policy.json" -Encoding UTF8
# Add the access policy
az rest --method PUT `
--uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connections/$connectionName/accessPolicies/$policyName?api-version=2018-07-01-preview" `
--body "@$env:TEMP\access-policy.json" `
-o jsonaz rest --method GET `
--uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connections/$connectionName/accessPolicies?api-version=2018-07-01-preview" `
-o jsonNote: ACL propagation can take 1-5 minutes. If you get 403 errors immediately after adding the policy, wait and retry.
Before testing in your application, verify the connection works:
# Replace with your actual runtime URL from Step 2
$runtimeUrl = "<your-runtime-url>"
# Test SharePoint - list available sites
az rest --method GET `
--uri "$runtimeUrl/datasets" `
--resource "https://apihub.azure.com" `
-o json
# Test Office365 - get categories
az rest --method GET `
--uri "$runtimeUrl/Categories" `
--resource "https://apihub.azure.com" `
-o jsonAdd the runtime URL to your application settings:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"Office365ConnectionRuntimeUrl": "<your-office365-runtime-url>",
"SharepointonlineConnectionRuntimeUrl": "<your-sharepoint-runtime-url>"
}
}{
"ConnectionRuntimeUrls": {
"Office365": "<your-office365-runtime-url>",
"Sharepointonline": "<your-sharepoint-runtime-url>"
}
}The generated connector clients (e.g., Office365Client, TeamsClient) authenticate to API Hub using Azure credentials. Each client provides overloaded constructors: a Uri-only overload that defaults to ManagedIdentityCredential, a Uri + TokenCredential overload for explicit credentials, and a string convenience overload that delegates to the Uri overload (validating the URL with Uri.TryCreate):
When no credential is specified, the client defaults to ManagedIdentityCredential with system-assigned identity. This is deterministic and production-ready.
// System-assigned managed identity (default)
var client = new Office365Client(connectionRuntimeUrl);The Function App must have system-assigned managed identity enabled, and the identity must have an access policy on the connection.
For local development, pass AzureCliCredential explicitly. This authenticates as your Azure CLI identity (az login).
var client = new Office365Client(
new Uri(connectionRuntimeUrl),
new AzureCliCredential());Your CLI identity must have an access policy on the connection for local testing.
Construct a ManagedIdentityCredential with a specific client ID and pass it explicitly.
var credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId("<client-id-of-user-assigned-msi>"));
var client = new Office365Client(
new Uri(connectionRuntimeUrl),
credential);Use this when multiple apps share a single identity, or when you need the identity to outlive any single app deployment.
| Mode | When to use | Access policy identity |
|---|---|---|
| ManagedIdentityCredential (default) | Production deployment, single-app scenarios | Function App's system-assigned MSI object ID |
| AzureCliCredential | Local development, quick prototyping | Your Azure CLI user object ID |
| User-assigned MSI | Production deployment, shared identity across apps | User-assigned MSI object ID |
Note: All three modes require an access policy granting the identity permission to use the connection. The only difference is which identity's object ID goes into the policy.
The Uri + TokenCredential constructor overload accepts any TokenCredential, enabling advanced scenarios (e.g., certificate-based auth, chained credentials):
var credential = new ChainedTokenCredential(
new ManagedIdentityCredential(ManagedIdentityId.SystemAssigned),
new AzureCliCredential());
var client = new Office365Client(new Uri(connectionRuntimeUrl), credential);The access policy hasn't propagated yet, or is missing. Solutions:
- Wait 1-5 minutes for propagation
- Verify the policy exists with the GET accessPolicies command
- Ensure the objectId matches your signed-in identity
The OAuth token has expired. Re-authorize using Step 4.
The connection was created as a classic ARM connection. Create a new connection through a Logic Apps Standard app.
The endpoint path may be incorrect. Check the connector's swagger/OpenAPI spec for valid paths.
- scripts/Setup-Connection.ps1 - Automated setup script
- ROADMAP.md - Connector generation progress and lessons learned
- DirectConnector Sample - Working example with Office 365, SharePoint, and Teams