---
title: "List ERP connections"
method: GET
path: "/v1/erp-connections"
tags: ["ERP sync"]
---

# List ERP connections

`GET /v1/erp-connections`

## Request

- Base URL: `https://api.getfinero.com/functions/v1/api`
- URL: `https://api.getfinero.com/functions/v1/api/v1/erp-connections`
- Auth: HTTP bearer

Lists the tenant's ERP connections (safe status metadata only — never credentials, hosts, or configuration). Connecting a new ERP and configuring what it syncs are managed inside the Finero app; starting a pull and changing the pull cadence can be done here.

Available to **admin and readonly** API keys (no side effects).

## Query parameters

- `limit` integer
- `cursor` string
- `order` 'asc' | 'desc'
- `include_total` boolean

## Response `200`

Success

- object
  - `data` object[], required: ERP connections.
    - `id` string, uuid, required: ERP connection id — use as connection_id when starting a sync run.
    - `provider` 'oracle_fusion' | 'xero', required: ERP system this connection syncs from: `oracle_fusion` (Oracle Fusion Cloud ERP) or `xero` (a Xero organisation, connected by signing in to Xero).
    - `pull_mode` 'rest_api' | 'publisher_report', required: How invoices are read from the ERP. `rest_api` reads the receivables REST resource with its payment schedules; `publisher_report` reads invoice headers from an Analytics Publisher report, so every invoice from that connection is collected as a whole — installments and contact names are never present. Both methods sync incrementally (changes since the last sync) and run a complete pass at least once a day, which is when an invoice that vanished from the ERP or from the report is marked no longer present. A `xero` connection always reads `rest_api`: Xero has no payment schedules, so its invoices are collected as a whole too. Read-only: the method is chosen when a workspace admin connects the ERP.
    - `payment_push_transport` 'rest' | 'soap', required: HOW a payment's receipt is pushed to the ERP. `rest` — the receivables REST resource. `soap` — the ERP's receipt SOAP services, offered only on a `publisher_report` connection, which then uses its report's SOAP user for everything and holds no OAuth client. A `xero` connection pushes `rest`: each payment is recorded in Xero against the invoice it paid. Either way an accepted receipt reads `erp_push_status: posted`. Read-only: the transport is chosen when a workspace admin connects the ERP.
    - `payment_push_mode` 'auto' | 'manual', required: WHEN a payment collected through Finero is pushed to the ERP as a receipt. `auto` — right after the payment settles, without anyone acting. `manual` — the receipt is created at settlement but HELD until a workspace admin releases it, one or many at a time (POST /v1/payments/erp-push); a held payment reads `erp_push_status: held`. Releasing pushes each receipt on its own, so one failure never affects another. Switching from manual to auto releases everything held on the connection. Set with POST /v1/erp-connections/{connectionId}/payment-push-mode.
    - `status` 'connected' | 'requires_reauthentication' | 'temporarily_unavailable' | 'disconnected', required: Connection health, and therefore whether the invoice data you are reading is CURRENT. `connected` means pulls are working. `requires_reauthentication` means the credential is missing, expired or revoked: scheduled pulls pause until a workspace admin reconnects it in the Finero app, so nothing new arrives and every figure is only as fresh as `last_successful_sync_at` - say so when you report numbers. `temporarily_unavailable` is the ERP being unreachable and usually clears itself. `disconnected` means the connection is switched off. In any state but `connected`, compare `last_successful_sync_at` against `last_sync_at`: a LATER `last_sync_at` means runs are still happening and not completing.
    - `last_sync_at` string, date-time, nullable, required: When a sync run last finished, whatever its outcome. Use last_successful_sync_at to judge freshness (ISO 8601 UTC).
    - `last_successful_sync_at` string, date-time, nullable, required: When a sync run last completed its walk of the ERP: a `success` run, or a `partial` one that only skipped invoices (its `error_summary` is null). Freshness of the imported data (ISO 8601 UTC).
    - `auto_sync_enabled` boolean, required: Whether scheduled auto-sync is on. False is the workspace's "off" choice - manual pulls still work, and `auto_sync_interval_minutes` keeps the cadence that applies when it is turned back on. True still requires connected health and a stored credential; reconnection restores the retained schedule after a missing-credential failure.
    - `auto_sync_interval_minutes` integer, required: How often Finero pulls this connection automatically, in minutes. A workspace admin chooses it: 10 to 1440 (24 hours). Read it together with `auto_sync_enabled` - when that is false there is no automatic pull at all and this value is simply the setting kept for when it is turned back on. It is a FLOOR rather than an appointment: a connection is pulled on the first scheduled check after this much time has passed, typically within a minute of it.
    - `pull_invoice_date_from` string, date, nullable, required: Oldest invoice date this connection imports, inclusive. null means no limit. This is why an invoice that exists in the ERP may be absent here: it is dated before the limit. Changing it never deletes invoices already imported (YYYY-MM-DD).
    - `created_at` string, date-time, required: Creation time (ISO 8601 UTC).
  - `pagination` object, required
    - `next_cursor` string, nullable, required: Opaque cursor for the next page — pass as ?cursor=. Null when there are no further results.
    - `has_more` boolean, required: Whether another page exists.
    - `limit` integer, required: The page size that was applied.
    - `total_count` integer: Total rows matching the filters, ignoring paging. Present ONLY when the request passed ?include_total=true.

## Other responses

- `400`: `invalid_cursor` — The cursor is malformed, was issued for a different query, or (aging) the report changed. Restart without cursor, keeping the filters identical. `validation_failed` — The request failed schema validation. See error.details for field messages.
- `401`: `invalid_credentials` — The credential is malformed or does not match an active key. The response never reveals whether a key identifier exists. `missing_credentials` — No Authorization: Bearer header was sent. `revoked_credentials` — The presented key was revoked. Create a new key in Settings → API.
- `403`: `feature_unavailable` — The tenant's tier does not currently include API access. Feature rollout flags cannot grant this entitlement. `permission_denied` — The key's permission does not allow this operation (readonly keys cannot call admin-only operations).
- `404`: `not_found` — No such resource in YOUR tenant. Ids belonging to another tenant are indistinguishable from missing ones.
- `429`: `rate_limit_exceeded` — Too many requests. Honor the Retry-After header (seconds) before retrying — waiting that long is enough. The RateLimit-* fields on every response say how much headroom is left before this happens; pace against them instead of retrying into a refusal.
- `500`: `internal_error` — Unexpected server error. Safe to retry with the same Idempotency-Key.

---

[API](https://skmtc.dev/getfinero/apis/finero-public-api.md) · [All operations](https://skmtc.dev/getfinero/apis/finero-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getfinero/apis/finero-public-api/revisions/3d456e222775?raw)
