Documentation

API and JavaScript documentation for integrating your software with LnkFi.

API

The LnkFi API offers endpoints to allow you to connect, disconnect, reauthorize, and proxy calls to supported systems.

The API is available at: https://api.lnkfi.com

POST

/v1/connection/authorize

Get an authorization URL for a system to establish a new connection or reauthorize an existing connection. Once a connection is authorized, you will receive a webhook at the address provided with the connection details.

Request

Headers

  • Content-TypeThe content type of the request. Should always be application/json.
    application/json

Parameters

  • systemThe system you are wanting to connect. Support systems include: xero.
    stringrequired
  • vendor_idYour vendor ID that is provided by LnkFi.
    stringrequired
  • vendor_external_idAn external ID that is used to identify which account or user in your system this connection belongs to.
    stringoptional
  • system_client_idThe client ID for the system selected. This is optional if passing existing_connection_id.
    stringrequired
  • system_client_secretThe client secret for the system selected. This is optional if passing existing_connection_id.
    stringrequired
  • vendor_redirect_urlAn HTTP or HTTPS URL to return the user to, with a result query parameter of success, canceled, or error. Success and cancellation redirect automatically; an authorization error page may provide a Return to app link.
    stringrequired
  • consent_givenRequired to be passed as true. You must display to the end user and obtain consent from them:

    I consent to [Your Company Name] and LnkFi using the data I have submitted here (including my user credentials to pull the applicable data from the Third Party Services associated with such user credentials) on my behalf, and to LnkFi providing that applicable data to [Your Company Name]. I agree that I have reviewed any applicable Third Party Service legal terms and have authority to send data to [Your Company Name] via LnkFi.This is optional if passing existing_connection_id.
    booleanrequired
  • instance_idThe Xero tenant to associate with this new or existing connection. Must be authorized after OAuth. When supplied on reconnect, explicitly replaces the previous association. If unavailable, the flow fails without changing the connection. Omit to use the default tenant resolution.
    stringoptional
  • existing_connection_idThe ID of an existing connection that is wanting to be reauthorized.
    stringoptional

Important

When passing in the system_client_id and system_client_secret, the application will need to whitelist LnkFi's redirect URI: https://link.lnkfi.com/v1/connection/authorize/<system>/complete

Response

Content-Type: application/json

Parameters

  • authorization_urlThe URL that you will redirect the user to in order to authorize the connection.
    string
  • systemThe system that the connection is for.
    string
  • vendor_idThe vendor ID that is provided by LnkFi.
    string
  • vendor_external_idThe external ID that is used to identify which account or user in your system this connection belongs to.
    string
  • existing_connection_idThe ID of an existing connection that is wanting to be reauthorized.
    string
  • authorized_instance_idThe stored Xero tenant ID for an existing connection. Null for a new connection or an existing connection whose tenant association has not been resolved. The completed flow returns its resolved association in the success webhook.
    string | null

Sample Response

{
  "authorization_url": "https://login.xero.com/....",
  "system": "xero",
  "vendor_id": "vnd_00000000-0000-0000-0000-000000000000",
  "vendor_external_id": "user_1234567890",
  "authorized_instance_id": null
}

Xero tenant selection

Use one LnkFi connection for multiple tenants, or create separate connections associated with individual tenants. Both retain the full instances list; every proxy request still requires its own instance_id and can target any authorized tenant. A stored association does not restrict the token's permissions.

Pass optional instance_id when connecting or reconnecting to explicitly choose the association. LnkFi verifies that tenant is authorized after OAuth, saves it as authorized_instance_id, and includes it in the success webhook. An unavailable requested tenant fails without saving or falling back. The initial authorization response reports the current stored association, not the pending choice.

Without an explicit instance_id, a new connection stores the tenant identified by the OAuth flow. If the flow does not identify exactly one tenant, LnkFi uses the sole authorized tenant when there is only one, or asks the user to choose one on a selection page when several remain. The connection is saved and its success webhook is sent only after the tenant is resolved. A flow with no authorized organisations shows an error.

The selection link expires ten minutes after OAuth completes. Cancelling returns the user to your redirect URL with result=canceled and sends no success webhook.

Without an explicit instance_id, reauthorizing a connection preserves its stored authorized_instance_id if that tenant is still in the authorized list. If the tenant is missing, reauthorization fails without replacing the connection or switching tenants. This check happens after OAuth; it does not restrict Xero's consent screen. Existing connections with a null association follow the same resolution and selection flow as new connections.

DELETE

/v1/connection

Disconnects an existing connection. A disconnected connection can be reauthorized at a later time if the ID is passed into the connection endpoint.

Request

Headers

  • Content-TypeThe content type of the request. Should always be application/json.
    application/json
  • AuthorizationThe authorization header for the request. Include the API Key for the connection.
    APIKey <api_key>

Parameters

  • vendor_idYour vendor ID that is provided by LnkFi.
    stringrequired
  • connection_idThe ID of the connection you are wanting to disconnect.
    stringrequired

Response

Content-Type: application/json

Parameters

  • statusThe status of the connection. This will be "disconnected" if the connection was successfully disconnected.
    string

Sample Response

{
  "status": "disconnected"
}
POST

/v1/connection/proxy

Proxies a request to the system's API on behalf of a connection.

Request

Headers

  • Content-TypeThe content type of the request. Should always be application/json.
    application/json
  • AuthorizationThe authorization header for the request. Include the API Key for the connection.
    APIKey <api_key>

Parameters

  • connection_idThe LnkFi connection_id from the webhook, identifying the connection you are wanting to proxy a request to. This is different from a Xero tenant ID.
    stringrequired
  • urlThe URL that you are wanting to proxy a request to.
    stringrequired
  • instance_idRequired on every Xero proxy request. Pass the tenant ID you want to target from instances. To target the associated organisation, explicitly pass authorized_instance_id. You may target a different authorized tenant; LnkFi does not default to or restrict requests to the stored association. Xero enforces the token's access to the requested tenant.
    stringrequired

Response

Content-Type: application/json

Headers

  • X-RateLimit-Day-RemainingThe number of requests remaining for the day.
    XXX
  • X-RateLimit-Minute-RemainingThe number of requests remaining for the minute.
    XXX

Sample Response

{
  "Id": "242a5822-db78-42d6-8d02-4061997d3f37",
  "Status": "OK",
  "ProviderName": "Reports",
  "DateTimeUTC": "/Date(1726845251839)/",
  "Reports": [
    {
      "ReportID": "BalanceSheet",
      "ReportName": "Balance Sheet",
      "ReportType": "BalanceSheet",
      "ReportTitles": [
        "Balance Sheet",
        "Testing",
        "As at 30 September 2024"
      ],
      "ReportDate": "20 September 2024",
      "UpdatedDateUTC": "/Date(1726845251839)/",
      "Fields": [],
      "Rows": [
        {
          "RowType": "Header",
          "Cells": [
            {
              "Value": ""
            },
            {
              "Value": "30 Sep 2024"
            },
            {
              "Value": "30 Sep 2023"
            }
          ]
        }
      ]
    }
  ]
}

Webhooks

LnkFi's webhooks provide a way to receive notifications when a connection is authorized, disconnected, or reauthorized.

Connection Webhooks

A successful new connection sends connection_completed. Reconnecting an existing connection sends connection_reauthorized. For Xero, both include instances, the full list of authorized tenants stored for the connection, and authorized_instance_id, the stored Xero tenant ID associated with the connection. The ID is a string or null for a legacy connection whose association has not been resolved; it is not a tenant object. A null association does not indicate cancellation.

Each id in these tenant objects is a Xero tenant ID, and display is the organisation name. The separate connection_id identifies the LnkFi connection, which can authorize access to multiple Xero tenants. For proxy requests, pass the LnkFi connection ID as connection_id and explicitly choose a tenant ID from instances as instance_id. Use authorized_instance_id to target the associated organisation, or another authorized tenant's ID to target that organisation. The stored association does not limit proxy access.

The REST authorization response also includes the stored authorized_instance_id. GraphQL exposes the same connection field as authorizedInstanceId, following its camelCase convention. REST fields and webhook payloads use snake_case.

Displaying connection instances

Keep both fields in your application. The instances array remains available in GraphQL and connection webhooks; authorized_instance_id supplements it and does not replace it. Display all instances from the array, and mark the instance whose id matches the stored association. GraphQL uses authorizedInstanceId for that association and instances for the full list.

Use each instance's display as its name and retain its id for identification and proxy requests. If the association is null, show it as unassigned and still display the full list. If the associated ID is absent from the list, show the stored ID separately without inventing a list entry. An associated instance is not necessarily the most recently authorized tenant and does not limit access to the other instances.

The list is the saved snapshot from the last successful OAuth connection or reconnection, not a live query of Xero. On a new successful connection webhook, replace your saved list with the supplied instances array and update the association independently. Do not filter the list down to the associated ID or accumulate stale entries from earlier snapshots.

Connection Completed Example

X-LnkFi-Webhook-Id: owh_00000000-0000-0000-0000-000000000000
X-LnkFi-Webhook-Vendor-Id: vnd_00000000-0000-0000-0000-000000000000
X-LnkFi-Webhook-Signature: xxxxx
User-Agent: LnkFi/1.0.0
Content-Type: application/json

{
  "type": "connection_completed",
  "system": "xero",
  "api_key": "xxxxxxx",
  "instances": [
    {
      "id": "be78c3f7-e85d-4cd7-8ef1-125718a2ef31",
      "display": "Acme"
    },
    {
      "id": "9f382b51-0a61-4e62-a73c-93a51c1252bc",
      "display": "Acme UK"
    }
  ],
  "authorized_instance_id": "9f382b51-0a61-4e62-a73c-93a51c1252bc",
  "connection_id": "con_00000000-0000-0000-0000-000000000000",
  "vendor_id": "vnd_xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "vendor_external_id": "1234567890"
}

Reconnection Example

After a new OAuth flow for an existing connection, the payload uses connection_reauthorized and the existing LnkFi connection_id. The full instances array can include other authorized tenants, while authorized_instance_id contains only the tenant ID associated with the connection.

{
  "type": "connection_reauthorized",
  "system": "xero",
  "api_key": "xxxxxxx",
  "instances": [
    {
      "id": "be78c3f7-e85d-4cd7-8ef1-125718a2ef31",
      "display": "Acme"
    },
    {
      "id": "9f382b51-0a61-4e62-a73c-93a51c1252bc",
      "display": "Acme UK"
    }
  ],
  "authorized_instance_id": "9f382b51-0a61-4e62-a73c-93a51c1252bc",
  "connection_id": "con_00000000-0000-0000-0000-000000000000",
  "vendor_id": "vnd_xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "vendor_external_id": "1234567890"
}

A connection_reauthorized webhook can also be sent after token-refresh recovery without an interactive OAuth flow. It includes the stored association and tenant list; it does not identify a newly authorized tenant.

Cancellation sends no success webhook.

When a connection needs reauthorization, the reauthorization_required webhook includes instances and the stored authorized_instance_id, which can be null for an unresolved legacy connection.

Verifying Webhooks

To verify that the webhook is coming from LnkFi, you can use the signature to verify the webhook. The signature is an HMAC-SHA256 hex encoded string using the vendor's webhook secret and the webhook's raw body.

The signature is sent in the X-LnkFi-Webhook-Signature header.

JavaScript Library

LnkFi's JavaScript Library provides pre-built UI that can be used to initiate connections through LnkFi on your company's app.

Authorize a new Connection via Web Component

You can use the provided web component to render the standard modal. data-open controls whether or not the modal is visible. Slots are provided for customization. Supported slots include an accessory to the right of the title for each step.

<script src="https://cdn.lnkfi.com/lnkfi.js"></script>
<lnkfi-modal
  data-open="true"
  data-vendor-id="vnd_00000000-0000-0000-0000-000000000000"
  data-system="xero"
  data-legal-name="Acme, Inc."
  data-redirect-url="http://acme.com/redirect"
  data-vendor-external-id="user_1234567890"
>
  <span slot="step-1-title-accessory"></span>
  <span slot="step-2-title-accessory"></span>
  <span slot="step-3-title-accessory"></span>
</lnkfi-modal>

Authorize a new Connection via Function

If you would rather open the modal via a function call, you can use the following example. Both openWidget and reauthorize accept optional instanceId. The HTML widget accepts the equivalent data-instance-id attribute.

<script src="https://cdn.lnkfi.com/lnkfi.js"></script>
<button
  onclick="window.lnkfi.openWidget({
  vendorId: 'vnd_00000000-0000-0000-0000-000000000000',
  legalName: 'Acme, Inc.',
  system: 'xero',
  redirectUrl: 'http://acme.com/redirect',
  vendorExternalId: 'user_1234567890',
})"
>
  Connect
</button>

Re-Authorize an Existing Connection

Pass the LnkFi connection_id from the webhook as existingConnectionId. A successful OAuth reconnection sends connection_reauthorized with the full instances array and authorized_instance_id, as described above. Pass optional instanceId to explicitly choose a tenant; omit it to retain the saved association. JavaScript options use camelCase and map to the REST instance_id field.

<script src="https://cdn.lnkfi.com/lnkfi.js"></script>
<button
  onclick="window.lnkfi.reauthorize({
  vendorId: 'vnd_00000000-0000-0000-0000-000000000000',
  system: 'xero',
  redirectUrl: 'http://acme.com/redirect',
  existingConnectionId: 'con_00000000-0000-0000-0000-000000000000',
  instanceId: '9f382b51-0a61-4e62-a73c-93a51c1252bc', // Optional
})"
>
  Re-Authorize
</button>