> ## Documentation Index
> Fetch the complete documentation index at: https://docs.synci.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Synci as a SimpleFIN provider

> Any SimpleFIN-compatible app can read a user's accounts, balances, and transactions from Synci. The Synci-specific details a consumer needs.

Synci is a [SimpleFIN](https://www.simplefin.org/protocol.html) data source. It implements the SimpleFIN protocol, so any SimpleFIN-compatible app can read a user's financial data (accounts, balances, and transactions) from Synci directly. The connection is read-only and scoped to the accounts the user chooses.

## If you build or run a finance app

**If your app already speaks SimpleFIN, it already works with Synci.** There is nothing Synci-specific to build: no partnership, no API keys to request, no Synci SDK. A user creates a Synci destination, copies a standard setup token, and pastes it into the same SimpleFIN screen your app already has. From your side it is an ordinary SimpleFIN source.

If SimpleFIN support is on your roadmap, implementing the [spec](https://www.simplefin.org/protocol.html) is all it takes: Synci then becomes a data source your users can pick, for free, the day you ship it.

What Synci brings to your users:

<Columns cols={3}>
  <Card title="Bank coverage beyond North America" icon="globe">
    European banks (via GoCardless) and New Zealand banks (via Akahu).
  </Card>

  <Card title="More than checking and savings" icon="trending-up">
    Investment, brokerage and crypto-exchange accounts are exposed as SimpleFIN accounts too.
  </Card>

  <Card title="Data users can shape" icon="wand-sparkles">
    Transactions reflect the user's Synci bank-account rules (payee cleanup, renaming), so what your app imports is already tidy.
  </Card>
</Columns>

[Actual Budget](https://actualbudget.org) is the officially supported and tested consumer (see the [Actual Budget setup guide](https://help.synci.io/articles/9212576-actual-budget)). Other SimpleFIN-compatible apps (Buckets, Sparky Budget, ZapYeti, EnvelopeBudget, and others) work through the same flow via the generic **SimpleFIN** destination; see [Apps powered by SimpleFIN](https://help.synci.io/articles/9818693-apps-powered-by-simplefin).

The rest of this page covers the Synci-specific details a consumer needs. For the protocol itself (the request/response format), see the [SimpleFIN spec](https://www.simplefin.org/protocol.html).

## Getting a setup token

<Steps>
  <Step title="Open the destination in Synci">
    Go to **Destinations** then **SimpleFIN** (or an app-specific page such as **Actual Budget**). The page is presentation only; the token it produces works with any SimpleFIN consumer.
  </Step>

  <Step title="Choose which accounts to expose">
    Share all of them, or a specific selection.
  </Step>

  <Step title="Copy the setup token">
    Copy the one-time **setup token**.
  </Step>
</Steps>

The setup token is a Base64-encoded claim URL. It can be claimed once, expires after about 7 days if unused, and can be regenerated from the destination's page (regenerating invalidates the previous token). Treat it as a secret.

## Claiming the token

The token exchange follows the standard SimpleFIN flow:

<Steps>
  <Step title="Decode the setup token">
    Base64-decode the setup token to get a claim URL.
  </Step>

  <Step title="Claim it once">
    `POST` the claim URL once. On success you receive an **access URL** as `text/plain`:

    ```text theme={"dark"}
    https://{username}:{password}@api.synci.io/simplefin
    ```

    The credentials are embedded in the URL. Store the access URL; the setup token is now spent.
  </Step>

  <Step title="Request accounts from then on">
    Request `{access URL}/accounts` using HTTP Basic auth built from the embedded `username:password`.
  </Step>
</Steps>

The host and path come from the token and the access URL, so a consumer never hardcodes them. A claim that has already been used, expired, or been revoked returns a `403` whose body begins with `Forbidden`.

Access credentials are revocable at any time from the destination's page in Synci. Once revoked, requests return `403`.

## Fetching accounts

`GET {access URL}/accounts` returns a SimpleFIN Account Set. It is called in two shapes:

<CodeGroup>
  ```http Balances only theme={"dark"}
  GET /accounts?balances-only=1
  ```

  ```http With transactions theme={"dark"}
  GET /accounts?start-date={epoch}&end-date={epoch}&pending=1&account={id}&account={id}
  ```
</CodeGroup>

**Balances only** (account discovery, no transactions) returns every exposed account with its balances and an empty `transactions` array.

**With transactions:**

* `start-date` / `end-date` are Unix timestamps in **seconds**. `end-date` is exclusive.
* `pending=1` includes not-yet-posted transactions.
* Repeat `account={id}` to limit the response to specific accounts. Ids not exposed by this connection are ignored.
* If `start-date` is omitted, the response is capped to roughly the last 90 days.

There is no pagination; each call returns a single JSON document.

## Response shape

```json theme={"dark"}
{
    "errors": [],
    "accounts": [
        {
            "org": {
                "domain": "inst-916407839591829.synci.io",
                "sfin-url": "https://api.synci.io/simplefin",
                "name": "DNB"
            },
            "id": "916407839591829",
            "name": "DNB Brukskonto",
            "currency": "NOK",
            "balance": "12345.67",
            "available-balance": "12000.00",
            "balance-date": 1767225600,
            "transactions": [
                {
                    "id": "935986745228429",
                    "posted": 1767139200,
                    "transacted_at": 1767052800,
                    "amount": "-129.00",
                    "description": "REMA 1000 OSLO",
                    "payee": "REMA 1000",
                    "pending": false
                }
            ]
        }
    ]
}
```

Synci-specific guarantees, beyond the base spec:

* **Amounts** (`balance`, `available-balance`, transaction `amount`) are signed decimal strings with exactly two decimal places. A negative amount is an outflow.
* **Timestamps** (`posted`, `transacted_at`, `balance-date`) are Unix seconds at noon UTC of the relevant calendar date.
* **Ids** (account `id`, transaction `id`) are stable across requests, so consumers can safely deduplicate on them.
* **`payee`** is always present and non-empty.
* A **pending** transaction always carries a `transacted_at`.
* **`org`** identifies the underlying institution, not Synci: `org.name` is the institution's name (for example "DNB") and `org.domain` is stable and unique per institution. Consumers that group accounts into "banks" by `org.domain` therefore get one bank per institution, and multiple accounts from the same institution are grouped together.
* `available-balance` is included only when Synci has one for the account.

## Limits and behavior

* **History:** roughly 90 days when no `start-date` is given.
* **Rate limit:** approximately 60 requests per hour per access credential.
* **Freshness:** responses are served from Synci's most recent provider sync, not live from the bank, so balances in particular can lag behind. There is no real-time fetch on request.
* Only bank-style account data is exposed (accounts, balances, transactions). No other part of the user's Synci account is reachable through these credentials.

## Versioning and stability

Synci advertises SimpleFIN version `1.0`, which the protocol's `info` endpoint reports as `{"versions":["1.0"]}`. An issued access URL is permanent for the life of the credential. Any breaking change would ship as a new protocol version and new credentials rather than altering an existing access URL, so a working integration keeps working.

## Security

* All requests are over HTTPS.
* Credentials are read-only and scoped to exactly the accounts the destination exposes. If the user shared all accounts, that scope includes accounts they connect to Synci later.
* Setup tokens are single-use with an expiry; access credentials are revocable at any time from Synci.
* Treat both the setup token and the access URL as secrets.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.