Building a Custom Connector to Xero in Power Platform
- Sofia Ng
- May 28
- 3 min read
I’ve recently been working on a small integration that turned out to be quite satisfying to put together, so I thought I’d share the process in case it’s useful to anyone facing a similar problem.
The setup: I needed to connect Microsoft’s Power Platform to Xero to pull in purchase orders and create bills automatically. Xero doesn’t have a native connector in Power Automate, which meant rolling up my sleeves and building a custom one.

Step 1: Swagger First
To get started, I created a Swagger (OpenAPI) definition that outlines the endpoints I needed:
Getting the current connection (to fetch the tenant ID)
Retrieving purchase orders using their ID
Creating bills in Xero
Here’s a base Swagger definition for Xero:
swagger: '2.0'
info:
title: Default title
description: ''
version: '1.0'
host: api.xero.com
basePath: /
schemes:
- https
consumes: []
produces: []
paths:
/api.xro/2.0/Invoices:
get:
responses:
default:
description: default
schema: {}
summary: GetInvoice
operationId: GetInvoice
parameters:
- name: Content-Type
in: header
required: false
type: string
- name: Accept
in: header
required: false
type: string
- name: xero-tenant-id
in: header
required: false
type: string
put:
responses:
default:
description: default
schema: {}
summary: Bill Creation
operationId: PutBill
parameters:
- name: Content-Type
in: header
required: false
type: string
- name: Accept
in: header
required: false
type: string
- name: xero-tenant-id
in: header
required: false
type: string
- name: body
in: body
required: false
schema:
type: object
properties:
Type:
type: string
description: Type
Contact:
type: object
properties:
Name:
type: string
description: Name
description: Contact
Date:
type: string
description: Date
DueDate:
type: string
description: DueDate
LineItems:
type: array
items:
type: object
properties:
Description:
type: string
description: Description
Quantity:
type: integer
format: int32
description: Quantity
UnitAmount:
type: integer
format: int32
description: UnitAmount
AccountCode:
type: string
description: AccountCode
description: LineItems
Reference:
type: string
description: Reference
Status:
type: string
description: Status
/connections:
get:
responses:
default:
description: default
schema:
type: array
items:
type: object
properties:
id:
type: string
description: id
authEventId:
type: string
description: authEventId
tenantId:
type: string
description: tenantId
tenantType:
type: string
description: tenantType
tenantName:
type: string
description: tenantName
createdDateUtc:
type: string
description: createdDateUtc
updatedDateUtc:
type: string
description: updatedDateUtc
summary: Get Connection
operationId: GetConnection
parameters: []
/api.xro/2.0/PurchaseOrders: {}
/api.xro/2.0/PurchaseOrders/{purchaseOrderId}:
get:
responses:
default:
description: default
schema: {}
summary: Purchase Order Get
operationId: GetPurchaseOrder
parameters:
- name: purchaseOrderId
in: path
required: true
type: string
- name: xero-tenant-id
in: header
required: false
type: string
definitions: {}
parameters: {}
responses: {}
securityDefinitions:
oauth2-auth:
type: oauth2
flow: accessCode
authorizationUrl: https://login.xero.com/identity/connect/authorize
tokenUrl: https://identity.xero.com/connect/token
scopes:
offline_access email openid profile accounting.transactions accounting.contacts accounting.settings.read: >-
offline_access email openid profile accounting.transactions
accounting.contacts accounting.settings.read
security:
- oauth2-auth:
- >-
offline_access email openid profile accounting.transactions
accounting.contacts accounting.settings.read
tags: []
It’s worth noting that Xero uses OAuth 2.0, so a bit of setup is required in their developer portal to get your client ID and secret. Once that’s configured, you can use this definition to register your connector inside Power Platform.
Step 2: Building the Flow
Once the connector was in place, I moved into Power Automate to build the actual flow. At a high level, it looks like this:
A scheduled trigger kicks off the flow (Recurrence).
It uses the custom connector to fetch a list of connections (to get the tenantid).
For each one, it retrieves the corresponding Purchase Order.
It then creates a new draft bill in Xero using the data from the PO.
A Quick Note on Permissions
The connector needs access to scopes like accounting.transactions, accounting.contacts, and so on. These are configured in the Swagger file and will be part of the OAuth consent process.
Why Bother?
It’s easy to overlook small bits of automation like this, especially when you’re surrounded by big shiny platforms promising out-of-the-box magic. But this kind of targeted, custom integration is where Power Platform really shines—especially when you want to automate around systems like Xero that don’t always play natively with Microsoft tools.
If you’re exploring something similar or want help to get started, let us know. Happy to share notes or tweaks from what we’ve learned along the way.