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

# Find ledger entries

> Finds the ledger entries that match the given filters, newest first.

One ledger entry is returned per booking. The VAT that Infinity books alongside an entry is folded into the entry's `vat` property instead of being returned as an entry of its own, so pagination counts bookings as you see them in the ledger.

## Finding ledger entries

A ledger entry is a single booking in the ledger: one amount, posted from a debit to a credit account on a date. You get one object per booking — the VAT that Infinity books alongside an entry is part of that entry, not a result of its own.

Entries are returned newest first. For example, the following request returns the entries posted to the bank account in January 2025:

```bash theme={null}
curl "https://api.infinity.swiss/v1/ledger-entries?account=1020&from=2025-01-01&to=2025-01-31" \
  -H "x-api-token: your-api-token"
```

A response with a single entry booked with VAT looks like this:

```json theme={null}
{
  "ledgerEntries": [
    {
      "id": "682338d9e9500b3ffe4baa5a",
      "date": "2025-02-05",
      "description": "Consulting revenue",
      "debitAccount": 1020,
      "creditAccount": 3400,
      "amount": 108100,
      "netAmount": 100000,
      "currency": "CHF",
      "vat": {
        "taxCode": "UN81",
        "rate": 8.1,
        "amount": 8100,
        "debitAccount": 1020,
        "creditAccount": 2200
      },
      "source": "manual",
      "reviewState": "reviewed",
      "receiptIds": ["686f1b2ce9500b3ffe4bbc71"],
      "createdAt": "2025-02-05T09:12:44.000Z",
      "updatedAt": "2025-02-05T09:12:44.000Z"
    }
  ]
}
```

All amounts are integer amounts in cents (`108100` = CHF 1081.00), and `amount` and `netAmount` are always in CHF. `amount` is the gross amount of the entry, `netAmount` the part of it that is booked between the debit and the credit account. Without VAT, the two are the same.

## VAT

The `vat` object is present for every entry that carries a tax code, and describes the VAT exactly as it stands in the ledger:

* `rate` and `amount` are the figures that were booked. With the simplified method (Saldosteuersatz), `rate` is the organisation's own simplified rate, and `statutoryRate` additionally tells you the statutory rate that the tax code stands for — for example a rate of 5.3% booked for a statutory rate of 8.1%.
* `amount` is `0` when no VAT was booked after all, for example because the VAT amount rounded to zero. In that case `debitAccount` and `creditAccount` are absent as well.
* `rate` is absent only for tax codes that are no longer defined.
* With reverse charge tax codes (acquisition tax, `BZB…` and `BZM…`), the VAT is booked on top of the entry rather than being contained in it. The entry's `amount` therefore equals its `netAmount`, and both `vat.debitAccount` and `vat.creditAccount` are VAT accounts.

## Foreign currencies

Entries that were posted in a currency other than CHF carry an `fx` object with the original amount, its currency, and the exchange rate that was used to convert it:

```json theme={null}
{
  "amount": 9500,
  "netAmount": 9500,
  "currency": "CHF",
  "fx": { "amount": 10000, "currency": "EUR", "exchangeRate": 0.95 }
}
```

The exchange rate is the value of one unit of the foreign currency in CHF, so `fx.amount` × `fx.exchangeRate` is the amount booked in CHF. It is absent only for legacy entries that were posted without a rate.

## Sources, receipts and reversals

* `source` tells you which part of Infinity the entry comes from, for example `manual`, `customer-invoice` or `bank`. See [ledger entry sources](/api/accounting/sources) for what each value means.
* `reviewState` tells you whether a person stands behind the entry. See [review state](#review-state) below.
* `receiptIds` contains the ids of the receipts attached to the entry. Use them with the [receipts endpoints](/api/receipts/attach) to attach further documents.
* `reversedBy` is present if the entry was reversed (Storno) and holds the id of the reversing entry. On the reversing entry itself — which has the source `reversal` — `reverses` points back at the original.

## Review state

With [AI accounting](/de/docs/accounting/ai-accounting/overview), Infinity posts entries from synchronised bank transactions on its own and asks the organisation to review them afterwards. `reviewState` tells you how far an entry has come:

| Review state | Meaning |
| - | - |
| `ai-proposed` | AI accounting posted the entry and nobody has reviewed it yet. Reviewing may still change or remove it. |
| `reviewed` | A person posted the entry, or reviewed one that AI accounting had posted. |

Entries that AI accounting never touched — posted by hand, through this API, or by another part of Infinity such as an invoice or the VAT settlement — are always `reviewed`. Most `ai-proposed` entries have the source `bank`, but not all of them: when AI accounting matches a bank transaction to an invoice, the resulting `customer-invoice` or `vendor-invoice` payment entry awaits review as well.

Treat `ai-proposed` entries as provisional when you copy the ledger elsewhere. Once a person reviews an entry, it is reported as `reviewed`, and its `updatedAt` moves, so [synchronising changes](#synchronising-changes) with `updatedSince` picks the transition up.

## Filtering

All filters are optional and can be combined:

* `from` and `to` limit the results to a date range, inclusive. Either can be used on its own.
* `account` returns entries in which the account appears as debit or as credit account, `debitAccount` and `creditAccount` only one side of the booking.
* `description` searches the description text of the entries.
* `taxCode` returns the entries booked with one tax code. Use the literal value `none` for entries booked without a tax code.
* `source` returns the entries from one source.
* `reviewState` returns the entries in one [review state](#review-state), for example the entries that still await review.
* `hasReceipt` returns the entries with at least one receipt attached (`true`) or without any (`false`).
* `updatedSince` returns the entries created or changed since a point in time.

For example, to find the expenses booked to the office supplies account, and the entries that still need a receipt:

```bash theme={null}
curl "https://api.infinity.swiss/v1/ledger-entries?debitAccount=6500&source=bank" \
  -H "x-api-token: your-api-token"
```

```bash theme={null}
curl "https://api.infinity.swiss/v1/ledger-entries?hasReceipt=false&from=2025-01-01" \
  -H "x-api-token: your-api-token"
```

To list the entries AI accounting posted that nobody has reviewed yet:

```bash theme={null}
curl "https://api.infinity.swiss/v1/ledger-entries?reviewState=ai-proposed" \
  -H "x-api-token: your-api-token"
```

Entries without VAT can be listed with `taxCode=none`:

```bash theme={null}
curl "https://api.infinity.swiss/v1/ledger-entries?taxCode=none" \
  -H "x-api-token: your-api-token"
```

## Synchronising changes

To keep a copy of the ledger up to date, remember the highest `updatedAt` you have seen and pass it as `updatedSince` on your next run. Entries that were posted or changed since then are returned, newest first:

```bash theme={null}
curl "https://api.infinity.swiss/v1/ledger-entries?updatedSince=2025-02-05T09:12:44.000Z" \
  -H "x-api-token: your-api-token"
```

<Note>
  Deletions are not reported by `updatedSince`. If entries may be deleted in
  Infinity, reconcile your copy periodically against a full listing of the
  relevant period instead of relying on incremental changes alone.
</Note>

## Pagination

Results are paginated with `limit` (default 30, at most 200) and `skip`, counting ledger entries. To page through all results, increase `skip` by the limit until fewer results than the limit are returned.


## OpenAPI

````yaml GET /v1/ledger-entries
openapi: 3.1.0
info:
  title: infinity.swiss Open API
  version: '1.0'
  summary: ''
servers:
  - url: https://api.infinity.swiss
security:
  - apiKey: []
paths:
  /v1/ledger-entries:
    get:
      tags: []
      summary: Find ledger entries
      description: >-
        Finds the ledger entries that match the given filters, newest first.


        One ledger entry is returned per booking. The VAT that Infinity books
        alongside an entry is folded into the entry's `vat` property instead of
        being returned as an entry of its own, so pagination counts bookings as
        you see them in the ledger.
      operationId: find-ledger-entries-v1
      parameters:
        - schema:
            type: string
            format: date
          in: query
          name: from
          description: Only return ledger entries dated on or after this date (YYYY-MM-DD).
          example: '2025-01-01'
        - schema:
            type: string
            format: date
          in: query
          name: to
          description: >-
            Only return ledger entries dated on or before this date
            (YYYY-MM-DD).
          example: '2025-12-31'
        - schema:
            type: integer
            minimum: 1000
            maximum: 9999
          in: query
          name: account
          description: >-
            Only return ledger entries posted to this account number, either as
            debit or as credit account.
          example: 1020
        - schema:
            type: integer
            minimum: 1000
            maximum: 9999
          in: query
          name: debitAccount
          description: >-
            Only return ledger entries whose debit account is this account
            number.
          example: 1020
        - schema:
            type: integer
            minimum: 1000
            maximum: 9999
          in: query
          name: creditAccount
          description: >-
            Only return ledger entries whose credit account is this account
            number.
          example: 3400
        - schema:
            type: string
            maxLength: 128
          in: query
          name: description
          description: Only return ledger entries whose description contains this text.
        - schema:
            type: string
          in: query
          name: taxCode
          description: >-
            Only return ledger entries booked with this tax code, either a
            statutory code such as `UN81` or a simplified code such as `SS53`.
            Set to `none` to only return entries that were booked without a tax
            code. Use [GET /v1/tax-codes](/api/accounting/tax-codes) to list the
            codes available to the organisation.
          example: UN81
        - schema:
            $ref: '#/components/schemas/LedgerEntrySource'
          in: query
          name: source
          description: Only return ledger entries that originate from this source.
          example: manual
        - schema:
            $ref: '#/components/schemas/LedgerEntryReviewState'
          in: query
          name: reviewState
          description: >-
            Only return ledger entries in this review state. Use `ai-proposed`
            to find the entries that AI accounting posted and nobody has
            reviewed yet.
          example: ai-proposed
        - schema:
            type: boolean
          in: query
          name: hasReceipt
          description: >-
            Set to `true` to only return ledger entries with at least one
            receipt attached, or to `false` to only return entries without any
            receipt.
        - schema:
            type: string
            format: date-time
          in: query
          name: updatedSince
          description: >-
            Only return ledger entries that were created or changed at or after
            this point in time, given as an ISO 8601 date-time with an offset.
            Deleted entries are not reported.
          example: '2025-02-05T09:12:44.000Z'
        - schema:
            type: number
            default: 30
            maximum: 200
          in: query
          name: limit
          description: >-
            Pagination limit for the results. Defaults to 30 if not specified.
            Maximum allowed value is 200.
        - schema:
            type: number
          in: query
          name: skip
          description: Pagination offset for the results
      responses:
        '200':
          description: Successfully returns the matching ledger entries, newest first.
          content:
            application/json:
              schema:
                type: object
                required:
                  - ledgerEntries
                properties:
                  ledgerEntries:
                    type: array
                    description: The ledger entries matching the query, newest first.
                    items:
                      $ref: '#/components/schemas/LedgerEntry'
        '400':
          description: >-
            A bad request is thrown if a query parameter is invalid or the limit
            exceeds the maximum allowed value.
          content:
            application/json:
              schema:
                type: object
                required:
                  - code
                properties:
                  code:
                    type: string
                    description: >-
                      The specific error code for this request.

                      May be:

                      - `general/missing-fields` when a query parameter is
                      malformed, for example an unknown `source` or
                      `reviewState`, a `hasReceipt` that is neither `true` nor
                      `false`, or an `updatedSince` that is not an ISO 8601
                      date-time

                      - `general/invalid-date` when `from` or `to` is not a
                      valid date

                      - `general/malformed-request` when `limit` exceeds 200 or
                      `skip` is invalid
                  invalidFields:
                    type: array
                    description: >-
                      A list of the fields which were invalid, if applicable,
                      such as `["source"]`, `["reviewState"]`, `["hasReceipt"]`
                      or `["updatedSince"]` for malformed filters, and
                      `["limit"]` or `["skip"]` for invalid pagination.
                    items:
                      type: string
                      example: source
        '401':
          $ref: '#/components/responses/Unauthorised'
components:
  schemas:
    LedgerEntrySource:
      title: LedgerEntrySource
      type: string
      description: >-
        Which part of Infinity a ledger entry originates from:

        - `manual`: posted by hand in Infinity, or through this API

        - `customer-invoice`: posted by a customer invoice (Forderung), for
        example its positions, payments, discounts or rebates

        - `vendor-invoice`: posted by a vendor invoice (Kreditor), for example
        its positions or payments

        - `bank`: posted from a synchronised bank transaction in Live Accounting

        - `vat`: posted by a VAT settlement or a VAT payment

        - `closing`: posted when a fiscal year is opened or closed, for example
        accruals, depreciation or the profit appropriation

        - `reversal`: posted to reverse another ledger entry (Storno)

        - `salary`: posted by a salary payment
      enum:
        - manual
        - customer-invoice
        - vendor-invoice
        - bank
        - vat
        - closing
        - reversal
        - salary
      example: manual
    LedgerEntryReviewState:
      title: LedgerEntryReviewState
      type: string
      description: >-
        Whether a person stands behind a ledger entry:

        - `ai-proposed`: AI accounting posted the entry from a synchronised bank
        transaction, and nobody has reviewed it yet. Treat it as provisional:
        reviewing may still change or remove it.

        - `reviewed`: a person posted the entry, or reviewed one that AI
        accounting had posted. Entries posted by hand, through this API, or by
        another part of Infinity are always `reviewed`.
      enum:
        - ai-proposed
        - reviewed
      example: reviewed
    LedgerEntry:
      title: LedgerEntry
      type: object
      description: >-
        A ledger entry is a single booking in the ledger: one amount, posted
        from a debit to a credit account on a date.


        Infinity books the VAT of an entry as a separate VAT transaction
        internally, but the API never returns it on its own: it is folded into
        the `vat` property of the entry it belongs to.
      required:
        - id
        - date
        - description
        - debitAccount
        - creditAccount
        - amount
        - netAmount
        - currency
        - source
        - reviewState
        - receiptIds
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          description: >-
            A unique hex identifier for the ledger entry. It stays the same when
            the entry is edited.
          example: 682338d9e9500b3ffe4baa5a
        date:
          type: string
          format: date
          description: The date of the ledger entry in YYYY-MM-DD format.
          example: '2025-02-05'
        description:
          type: string
          description: The single text-line description of the ledger entry.
          example: Consulting revenue
        debitAccount:
          type: integer
          minimum: 1000
          maximum: 9999
          description: The account number of the debit account of the ledger entry.
          example: 1020
        creditAccount:
          type: integer
          minimum: 1000
          maximum: 9999
          description: The account number of the credit account of the ledger entry.
          example: 3400
        amount:
          type: integer
          description: >-
            The gross amount of the ledger entry in cents (e.g. 108100 =
            1081.00), in CHF.


            For entries without VAT, this is the same as `netAmount`. It is also
            the same for reverse charge tax codes (acquisition tax), where the
            VAT is booked on top of the entry instead of being contained in it.
          example: 108100
        netAmount:
          type: integer
          description: >-
            The amount in cents that is booked between the debit and the credit
            account, in CHF, without the VAT booked alongside it.
          example: 100000
        currency:
          type: string
          minLength: 3
          maxLength: 3
          description: >-
            The 3-character alphanumeric currency code (ISO 4217) of `amount`
            and `netAmount`. These are always given in the accounting currency,
            which currently is always `CHF`. The currency the entry was posted
            in is reported in `fx`.
          example: CHF
        vat:
          $ref: '#/components/schemas/LedgerEntryVat'
          description: >-
            The VAT booked with this entry. Present for every entry that has a
            tax code.
        fx:
          $ref: '#/components/schemas/LedgerEntryFx'
          description: >-
            The original amount of this entry in a foreign currency. Present for
            every entry that was posted in a currency other than CHF.
        source:
          $ref: '#/components/schemas/LedgerEntrySource'
          description: Which part of Infinity this entry originates from.
        reviewState:
          $ref: '#/components/schemas/LedgerEntryReviewState'
          description: >-
            Whether a person stands behind this entry, or AI accounting posted
            it and it still awaits review.
        receiptIds:
          type: array
          description: >-
            The ids of the receipts attached to this ledger entry, in the order
            in which they were attached.
          items:
            type: string
            example: 686f1b2ce9500b3ffe4bbc71
        reversedBy:
          type: string
          description: >-
            The id of the ledger entry that reverses this entry (Storno). Only
            present if the entry has been reversed; such an entry can no longer
            be deleted.
          example: 6851f42ae9500b3ffe4bb0c4
        reverses:
          type: string
          description: >-
            The id of the ledger entry that this entry reverses. Only present
            for entries with the source `reversal`.
          example: 682338d9e9500b3ffe4baa5a
        createdAt:
          type: string
          format: date-time
          description: The time at which the ledger entry was created.
          example: '2025-02-05T09:12:44.000Z'
        updatedAt:
          type: string
          format: date-time
          description: >-
            The time at which the ledger entry was last changed. Use it together
            with the `updatedSince` filter to synchronise changes incrementally.
          example: '2025-02-05T09:12:44.000Z'
    LedgerEntryVat:
      title: LedgerEntryVat
      type: object
      description: >-
        The VAT that was booked with a ledger entry, as it stands in the ledger.


        With reverse charge tax codes (acquisition tax, `BZB…` and `BZM…`), the
        VAT is booked on top of the entry rather than contained in it: the
        `amount` of the entry equals its `netAmount`, and the VAT booking runs
        between two VAT accounts.
      required:
        - taxCode
        - amount
      properties:
        taxCode:
          type: string
          description: >-
            The tax code of the ledger entry, either a statutory code such as
            `UN81`, or one of the organisation's own simplified codes
            (Saldosteuersatz) such as `SS53`.
          examples:
            - UN81
            - SS53
        rate:
          type: number
          description: >-
            The VAT rate in percent that was actually booked, e.g. `8.1`. With
            the simplified method (Saldosteuersatz), this is the organisation's
            simplified rate, e.g. `5.3`.


            Absent only for tax codes that are no longer defined.
          example: 8.1
        statutoryRate:
          type: number
          description: >-
            The statutory VAT rate in percent that the tax code stands for, e.g.
            `8.1`. Only present for simplified tax codes (Saldosteuersatz),
            where the rate charged to the customer differs from the rate booked.
          example: 8.1
        amount:
          type: integer
          description: >-
            The VAT amount in cents that was booked, in CHF.


            `0` if no VAT booking was made after all, for example because the
            VAT amount rounded to zero.
          example: 8100
        debitAccount:
          type: integer
          minimum: 1000
          maximum: 9999
          description: >-
            The account number of the debit account of the VAT booking. Absent
            if no VAT booking was made.
          example: 1020
        creditAccount:
          type: integer
          minimum: 1000
          maximum: 9999
          description: >-
            The account number of the credit account of the VAT booking. Absent
            if no VAT booking was made.
          example: 2200
    LedgerEntryFx:
      title: LedgerEntryFx
      type: object
      description: >-
        The foreign currency details of a ledger entry. Only present if the
        entry has an amount in a foreign currency; the amounts of the entry
        itself are always converted to CHF.
      required:
        - amount
        - currency
      properties:
        amount:
          type: integer
          description: >-
            The gross amount of the ledger entry in cents (e.g. 10000 = 100.00),
            in the foreign currency.
          example: 10000
        currency:
          type: string
          minLength: 3
          maxLength: 3
          description: >-
            The 3-character alphanumeric currency code (ISO 4217) of the foreign
            currency.
          example: EUR
        exchangeRate:
          type: number
          description: >-
            The exchange rate that was used to convert the amount, as the value
            of one unit of the foreign currency in CHF. Absent only for legacy
            entries that were posted without a rate.
          example: 0.95
  responses:
    Unauthorised:
      description: >-
        An unauthorised request was submitted. You may be using an incorrect or
        expired API token, or are attempting to access a document outside of the
        scope of the token.
      content:
        application/json:
          schema:
            type: object
            properties:
              code:
                type: string
                x-stoplight:
                  id: 08hkw8ukmi2lp
                description: Specific error code
          examples:
            Unauthorised request:
              value:
                code: general/unauthorised
  securitySchemes:
    apiKey:
      name: x-api-token
      type: apiKey
      in: header
      description: >-
        API token for authentication. Obtain from your Infinity account
        settings.

````

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