# Query data

Source: https://fragment.dev/guides/query-data

[Documentation index](https://fragment.dev/llms.txt)

<a id="query-data"></a>

You can flexibly query your data to generate financial reports, embed Fragment in your product and build internal dashboards.

[Visual: queryData. View on the HTML page.](https://fragment.dev/guides/query-data)

<a id="basics"></a>

## Basics

<a id="basics-graphql"></a>

### GraphQL

Fragment is a GraphQL API, so data in the system is modeled as a graph. Entities in the API are nodes, and their relationships with other entities are edges. Ledgers have Ledger Accounts; Ledger Accounts and Ledger Entries have Ledger Lines; and so on.

Fragment exposes several [queries](https://fragment.dev/markdown/api-reference/ledger-queries.md) as entry points to the data graph. They return data about a single entity, or a list of entities.

When making a query, you can fetch related entities using expansions. As opposed to a REST interface, where you may require several round-trips to query nested data, expansions are nested queries that you let you retrieve related data in a single request.  For example, you can [expand from a Ledger Entry to all the Ledger Lines](https://fragment.dev/markdown/guides/query-data.md#ledger-entries-expand-lines) in it in one API call.

<a id="basics-connection-types"></a>

### Connection types

Fragment uses [connection types](https://relay.dev/graphql/connections.htm) to return lists of entities. A connection type is a list of nodes, and a `pageInfo` object that contains cursors to the next and previous pages of results.

```graphql title="ListLedgerAccounts"
query ListLedgerAccounts($ledger: LedgerMatchInput!) {
  ledger(ledger: $ledger) {
    ledgerAccounts {
      nodes {
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

<a id="basics-filtering"></a>

### Filtering

You can filter connection types with a `filter` argument.

For example, you can filter a list of Ledger Accounts by their type:

```graphql title="FilterLedgerAccounts query"
query FilterLedgerAccounts(
    $ledger: LedgerMatchInput!,
    $filter: LedgerAccountsFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerAccounts {
      nodes {
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="FilterLedgerAccounts variables - by type"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "type": {
      "equalTo": "asset"
    }
  }
}
```

You can combine filters by adding multiple components to the filter block. Results are AND'd:

```json title="FilterLedgerAccounts variables - by type"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "type": {
      "equalTo": "asset",
      "hasParentLedgerAccount": true
    }
  }
}
```

<a id="basics-pagination"></a>

### Pagination

Fields that return lists support cursor-based pagination:

- Results are returned under a `nodes` property as an array. The `pageInfo` property contains cursors pointing to the next page and previous pages.
- You can send a cursor to the `after` (or `before`) arguments on list fields to retrieve a specific page.
- The `first` (or `last`) argument sets the page size. The default is 20 and the maximum is 200.
- Once a page size has been set in the initial request, all subsequent pagination requests have to use the same page size.
- Results are returned in a deterministic order. This is generally reverse chronological, newest first. This sort is by posted date for Ledger Lines and Ledger Entries, or creation date for other entities.

This query uses pagination to retrieve two Ledger Accounts at a time:

```graphql title="GetLedgerAccounts query with pagination"
query GetLedgerAccounts(
  $ledgerIk: SafeString!
  $after: String
  $first: Int
  $before: String
) {
  ledger(ledger: { ik: $ledgerIk }) {
    ledgerAccounts(
      after: $after
      first: $first
      before: $before
    ) {
      nodes {
        path
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="GetLedgerAccounts variables"
{
  "ledgerIk": "ik-used-to-create-ledger",
  "first": 2
}
```

The response is:

```json title="GetLedgerAccounts first page response"
{
  "data": {
    "ledger": {
      "ledgerAccounts": {
        "nodes": [
          {
            "path": "assets/test-assets/test:1",
            "name": "Test 1",
            "type": "asset"
          },
          {
            "path": "assets/test-assets/test:2",
            "name": "Test 2",
            "type": "asset"
          }
        ],
        "pageInfo": {
          "hasNextPage": true,
          "endCursor": "<some-end-cursor>",
          "hasPreviousPage": false,
          "startCursor": null
        }
      }
    }
  }
}
```

To retrieve the next page, send the same query but with the `after` parameter set on `ledgerAccounts`:

```json title="GetLedgerAccounts next page variables"
{
  "ledgerIk": "ik-used-to-create-ledger",
  "after": "<some-end-cursor>"
}
```

The response is:

```json title="GetLedgerAccounts second page response"
{
  "data": {
    "ledger": {
      "ledgerAccounts": {
        "nodes": [
          {
            "path": "assets/test-assets/test:3",
            "name": "Test 3",
            "type": "asset"
          },
          {
            "path": "assets/test-assets/test:4",
            "name": "Test 4",
            "type": "asset"
          }
        ],
        "pageInfo": {
          "hasNextPage": false,
          "endCursor": null,
          "hasPreviousPage": true,
          "startCursor": "<some-start-cursor>"
        }
      }
    }
  }
}
```

To retrieve the previous page of results, send the same query but with the `before` parameter set on `ledgerAccounts`. The response is the first page of results.

```json title="GetLedgerAccounts previous page variables"
{
  "ledgerIk": "ik-used-to-create-ledger",
  "before": "<some-start-cursor>"
}
```

<a id="ledgers"></a>

## Ledgers

<a id="ledgers-lookup"></a>

### Lookup

Use the `ledger` query to retrieve a Ledger by the IK used to create it:

```graphql title="GetLedger"
query GetLedger($ledger: LedgerMatchInput!) {
  ledger(ledger: $ledger) {
    name
    created
    balanceUTCOffset
    ledgerAccounts {
      nodes {
        name
        type
      }
    }
    schema {
      key
    }
  }
}
```

```json title="GetLedger variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  }
}
```

<a id="ledgers-list"></a>

### List

Use the `ledgers` query to list all the Ledgers in your workspace:

```graphql title="ListLedgers"
query ListLedgers {
  ledgers {
    nodes {
      name
      created
      balanceUTCOffset
      ledgerAccounts {
        nodes {
          name
          type
        }
      }
      schema {
        key
      }
    }
    pageInfo {
      hasNextPage
      endCursor
      hasPreviousPage
      startCursor
    }
  }
}
```

The response is a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of Ledgers.

<a id="ledger-accounts"></a>

## Ledger Accounts

<a id="ledger-accounts-lookup"></a>

### Lookup

Use the `ledgerAccount` query to retrieve a Ledger Account by its path in the Schema:

```graphql title="GetLedgerAccount"
query GetLedgerAccount(
  $ledgerAccount: LedgerAccountMatchInput!
) {
  ledgerAccount(ledgerAccount: $ledgerAccount) {
    path
    name
    balance
    type
    lines {
      nodes {
        amount
        posted
      }
    }
  }
}
```

The IK of the Ledger needs to be provided along with the Ledger Account's path:

```json title="GetLedgerAccount Variables"
{
  "ledgerAccount": {
    "path": "assets/banks/user-cash",
    "ledger": {
      "ik": "quickstart-ledger"
    }
  }
}
```

<a id="ledger-accounts-lookup-multiple"></a>

### Lookup multiple

You can also retrieve multiple Ledger Accounts using the `ledgerAccounts` query and the `in` filter:

```graphql title="ListLedgerAccounts"
query ListLedgerAccounts($ledger: LedgerMatchInput!, $filter: LedgerAccountsFilterSet) {
  ledger(ledger: $ledger) {
    ledgerAccounts(filter: $filter) {
      nodes {
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="GetLedgerAccount Variables with In"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "ledgerAccount": {
      "in": [
        {
          "path": "assets/banks/user-cash"
        },
        {
          "path": "income-root/income-revenue-root"
        }
      ]
    }
  }
}
```

<a id="ledger-accounts-list"></a>

### List

Use the `ledger.ledgerAccounts` query to list all Ledger Accounts within a Ledger:

```graphql title="ListLedgerAccounts"
query ListLedgerAccounts($ledger: LedgerMatchInput!) {
  ledger(ledger: $ledger) {
    ledgerAccounts {
      nodes {
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="ListLedgerAccounts variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  }
}
```

The response is a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of Ledger Accounts.

<a id="ledger-accounts-balances"></a>

### Balances

To read balances for Ledger Accounts, see:
- [Read balances](https://fragment.dev/markdown/guides/read-balances.md) for single-currency accounts
- [Handle currencies](https://fragment.dev/markdown/guides/handle-currencies.md#read-balances) for multi-currency accounts

<a id="ledger-accounts-filter-by-type"></a>

### Filter by type

Use the `type` parameter to filter Ledger Account lists:

```graphql title="FilterLedgerAccounts query"
query FilterLedgerAccounts(
    $ledger: LedgerMatchInput!,
    $filter: LedgerAccountsFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerAccounts(filter: $filter) {
      nodes {
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

Use `type` to filter Ledger Accounts by their type:

```json title="FilterLedgerAccounts variables - by type"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "type": {
      "equalTo": "asset"
    }
  }
}
```

You can also filter for multiple types in one query, using `in`. This can be useful to [Generate reports](https://fragment.dev/markdown/guides/generate-reports.md):

```json title="FilterLedgerAccounts variables - type in"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "type": {
      "in": ["asset", "liability"]
    }
  }
}
```

<a id="ledger-accounts-filter-by-path"></a>

### Filter by path

Use `path` and wildcard matching (`*`) in place of template variables to query all instances of Ledger Accounts with `template: true`.

```graphql title="FilterLedgerAccounts query"
query FilterLedgerAccounts(
    $ledger: LedgerMatchInput!,
    $filter: LedgerAccountsFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerAccounts(filter: $filter) {
      nodes {
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="FilterLedgerAccounts variables - by external account"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "path": {
      "matches": "liability-root/user:*/pending"
    }
  }
}
```

Read more about filtering Ledger Accounts in [filtering](https://fragment.dev/markdown/guides/query-data.md#basics-filtering).

<a id="ledger-accounts-filter-by-link"></a>

### Filter by Link

Use `linkedAccount` to filter Ledger Accounts by the External Account they're linked to:

```graphql title="FilterLedgerAccounts query"
query FilterLedgerAccounts(
    $ledger: LedgerMatchInput!,
    $filter: LedgerAccountsFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerAccounts(filter: $filter) {
      nodes {
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="FilterLedgerAccounts variables - by external account"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "linkedAccount": {
      "in": [
        {
          "linkId": "<link id>",
          "externalId": "account-id-at-bank"
        },
        {
          "linkId": "<link id>",
          "externalId": "account2-id-at-bank"
        }
      ]
    }
  }
}
```

<a id="ledger-accounts-filter-by-parent"></a>

### Filter by parent

Use `hasParentLedgerAccount` to filter Ledger Accounts by their parent status:

```graphql title="FilterLedgerAccounts query"
query FilterLedgerAccounts(
    $ledger: LedgerMatchInput!,
    $filter: LedgerAccountsFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerAccounts(filter: $filter) {
      nodes {
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="FilterLedgerAccounts variables - by external account"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "hasParentLedgerAccount": false
  }
}
```

Read more about filtering Ledger Accounts in [filtering](https://fragment.dev/markdown/guides/query-data.md#basics-filtering).

<a id="ledger-lines"></a>

## Ledger Lines

<a id="ledger-lines-lookup"></a>

### Lookup

Use the `ledgerLine` query to retrieve a Ledger Line by its ID:

```graphql title="GetLedgerLine"
query GetLedgerLine(
  $ledgerLine: LedgerLineMatchInput!
) {
  ledgerLine(ledgerLine: $ledgerLine) {
    amount
    currency {
      code
      customCurrencyId
    }
    account {
      name
      type
    }
  }
}
```

```json title="FilterLedgerAccountLines Variables"
{
  "ledgerLine": {
    "id": "<ledger line ID>"
  }
}
```

<a id="ledger-lines-list"></a>

### List

Use the `ledgerAccount.lines` query to list the lines in a Ledger Account:

```graphql title="GetLedgerAccountLines"
query GetLedgerAccountLines(
  $ledgerAccount: LedgerAccountMatchInput!
) {
  ledgerAccount(ledgerAccount: $ledgerAccount) {
    path
    name
    lines {
      nodes {
        amount
        currency {
          code
          customCurrencyId
        }
      }
    }
  }
}
```

```json title="GetLedgerAccountLines Variables"
{
  "ledgerAccount": {
    "path": "assets/banks/user-cash",
    "ledger": {
      "ik": "quickstart-ledger"
    }
  }
}
```

<a id="ledger-lines-filter-by-posted"></a>

### Filter by posted

Use `posted` to filter Ledger Lines by their posted timestamp between any two points in time:

```graphql title="FilterLedgerAccountLines"
query GetLedgerAccountLines(
  $ledgerAccount: LedgerAccountMatchInput!,
  $filter: LedgerLinesFilterSet!
) {
  ledgerAccount(ledgerAccount: $ledgerAccount) {
    path
    name
    lines(filter: $filter) {
      nodes {
        id
        amount
        currency {
          code
          customCurrencyId
        }
      }
    }
  }
}
```

```json title="FilterLedgerAccountLines Variables"
{
  "ledgerAccount": {
    "path": "assets/banks/user-cash",
    "ledger": {
      "ik": "quickstart-ledger"
    }
  },
  "filter": {
    "posted": {
      "after": "1969-07-01T00:00:00.000Z",
      "before": "1969-07-30T23:59:59.999Z"
    }
  }
}
```

The `after` and `before` filters are inclusive, so use timestamps for the first and last moments of the period you're querying for.

<a id="ledger-lines-filter-by-key"></a>

### Filter by key

Use `key` to filter Ledger Lines by their keys in your Schema:

```graphql title="FilterLedgerAccountLines"
query GetLedgerAccountLines(
  $ledgerAccount: LedgerAccountMatchInput!,
  $filter: LedgerLinesFilterSet!
) {
  ledgerAccount(ledgerAccount: $ledgerAccount) {
    path
    name
    lines(filter: $filter) {
      nodes {
        id
        amount
        currency {
          code
          customCurrencyId
        }
      }
    }
  }
}
```

```json title="FilterLedgerAccountLines Variables"
{
  "ledgerAccount": {
    "path": "assets/banks/user-cash",
    "ledger": {
      "ik": "quickstart-ledger"
    }
  },
  "linesFilter": {
    "key": {
      "equalTo": "increase_user_balance"
    }
  }
}
```

<a id="ledger-entries"></a>

## Ledger Entries

<a id="ledger-entries-lookup"></a>

### Lookup

Use the `ledgerEntry` query to retrieve a Ledger Entry by its IK. You provide the IK when posting entries via `addLedgerEntry`:

```graphql title="GetLedgerEntry"
query GetLedgerEntry(
  $ledgerEntry: LedgerEntryMatchInput!
) {
  ledgerEntry(ledgerEntry: $ledgerEntry) {
    id
    ik
    ledger {
      id
      name
    }
    lines {
      nodes {
        amount
        currency {
          code
          customCurrencyId
        }
      }
    }
  }
}
```

```json title="GetLedgerEntry Variables - by IK"
{
  "ledgerEntry": {
    "ik": "<ledger entry IK>"
  }
}
```

When you [Reconcile transactions](https://fragment.dev/markdown/guides/reconcile-payments.md#reconcile-a-tx) using `reconcileTx`, the IK is the Transaction's `externalId`. Query `entry.ik` in `ReconcileTxResult` to retrieve it:

```graphql title="Querying IK in reconcileTx"
mutation ReconcileTx(
  $entry: LedgerEntryInput!
) {
  reconcileTx(entry: $entry) {
    ... on ReconcileTxResult {
      entry {
        ik
        type
        created
        posted
      }
      lines {
        amount
        account {
          path
        }
      }
    }
    ... on Error {
      code
      message
    }
  }
}
```

A Ledger Entry can also be retrieved using its ID:

```json title="GetLedgerEntry Variables - by ID"
{
  "ledgerEntry": {
    "id": "<ledger entry ID>"
  }
}
```

<a id="ledger-entries-lookup-multiple"></a>

### Lookup multiple

You can also retrieve multiple Ledger Entries using the `ledgerEntries` query and the `in` filter:

```graphql title="ListLedgerEntries"
query ListLedgerEntries(
  $ledger: LedgerMatchInput!
  $filter: LedgerEntriesFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerEntries(filter: $filter) {
      nodes {
        ik
        type
        posted
        lines {
          nodes {
            amount
            account {
              path
            }
          }
        }
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="ListLedgerEntries Variables with In"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "ledgerEntry": {
      "in": [
        {
          "ik": "fund-user-1-account"
        },
        {
          "ik": "fund-user-2-account"
        }
      ]
    }
  }
}
```

<a id="ledger-entries-list-by-group"></a>

### List by group

You can get a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of Ledger Entries in a given group using the `ledgerEntryGroup.ledgerEntries` expansion:

```graphql title="GetGroupedLedgerEntries"
query GetGroupedLedgerEntries(
  $ledger: LedgerMatchInput!,
  $ledgerEntryGroup: EntryGroupMatchInput!,
) {
  ledger(ledger: $ledger) {
    ledgerEntryGroup(ledgerEntryGroup: $ledgerEntryGroup) {
      ledgerEntries {
        nodes {
          ik
          description
          posted
        }
        pageInfo {
          endCursor
          hasNextPage
          hasPreviousPage
          startCursor
        }
      }
    }
  }
}
```

```json title="GetGroupedLedgerEntries Variables"
{
  "ledgerEntryGroup": {
    "key": "withdrawal",
    "value": "12345"
  },
  "ledger": {
    "ik": "quickstart-ledger"
  }
}
```

The response is:

```json title="GetGroupedLedgerEntries Response"
{
  "data": {
    "ledger": {
      "ledgerEntryGroup": {
        "ledgerEntries": {
          "nodes": [
            {
              "ik": "ledger-entry-2",
              "description":"User user-id withdrawal settled",
              "posted": "1969-06-21T02:56:05.000Z"
            },
            {
              "ik": "ledger-entry-1",
              "description": "User user-id initiated withdrawal for 50000.",
              "posted": "1969-06-16T13:32:00.000Z"
            }
          ],
          "pageInfo": {
            "hasNextPage": false,
            "endCursor": null,
            "hasPreviousPage": false,
            "startCursor": null
          }
        }
      }
    }
  }
}
```

<a id="ledger-entries-list-hidden"></a>

### List hidden

Use the `showHidden` filter to get a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of all Ledger Entries, including those hidden by reversals.

```graphql title="FilterLedgerEntries"
query FilterLedgerEntries(
  $ledger: LedgerMatchInput!,
  $entriesFilter: LedgerEntriesFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerEntries(filter: $entriesFilter) {
      nodes {
        ik
        type
        posted
        hidden
      }
    }
  }
}
```

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "showHidden": true
  }
}
```

<a id="ledger-entries-expand-lines"></a>

### Expand lines

Use the `ledgerEntry.lines` expansion to list the Ledger Lines in a Ledger Entry:

```graphql title="GetLedgerEntryLines"
query GetLedgerEntryLines(
  $ledgerEntry: LedgerEntryMatchInput!
) {
  ledgerEntry(ledgerEntry: $ledgerEntry) {
    id
    ik
    lines {
      nodes {
        account {
          path
        }
        amount
        currency {
          code
          customCurrencyId
        }
      }
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="GetLedgerEntryLines Variables"
{
  "ledgerEntry": {
    "ik": "<ledger entry IK>"
  }
}
```

<a id="ledger-entries-filter-by-posted"></a>

### Filter by posted

Similar to Ledger Lines, Ledger Entries can be filtered by their posted timestamp between any two points in time using `posted`:

```graphql title="FilterLedgerEntries"
query FilterLedgerEntries(
  $ledger: LedgerMatchInput!,
  $entriesFilter: LedgerEntriesFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerEntries(filter: $entriesFilter) {
      nodes {
        ik
        type
        posted
        lines {
          nodes {
            amount
            account {
              path
            }
          }
        }
      }
    }
  }
}
```

Use `after` and `before` to filter Ledger Entries by their posted timestamp between any two points in time:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "posted": {
      "after": "1968-01-01",
      "before": "1969-01-01"
    }
  }
}
```

Use `date` to filter Ledger Entries by the date they were posted on:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "date": {
      "equalTo": "12-31-1968"
    }
  }
}
```

<a id="ledger-entries-filter-by-type"></a>

### Filter by type

Use `type` to filter Ledger Entries by their type as defined in your Schema:

```graphql title="FilterLedgerEntries"
query FilterLedgerEntries(
  $ledger: LedgerMatchInput!,
  $entriesFilter: LedgerEntriesFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerEntries(filter: $entriesFilter) {
      nodes {
        ik
        type
        posted
        lines {
          nodes {
            amount
            account {
              path
            }
          }
        }
      }
    }
  }
}
```

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "type": {
      "equalTo": "withdrawal"
    }
  }
}
```

To retrieve Ledger Entries of multiple types, use the `in` operator:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "type": {
      "in": ["withdrawal", "p2p_transfer"]
    }
  }
}
```

<a id="ledger-entries-filter-by-typeversion"></a>

### Filter by typeVersion

Use `typeVersion` to filter Ledger Entries by [typeVersion](https://fragment.dev/markdown/guides/migrate-data.md#updating-entry-types) as defined in your Schema. It is not required but often useful to combine this with a `type` filter. Note that `typeVersion` is a String filter:

```graphql title="FilterLedgerEntries"
query FilterLedgerEntries(
  $ledger: LedgerMatchInput!,
  $entriesFilter: LedgerEntriesFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerEntries(filter: $entriesFilter) {
      nodes {
        ik
        type
        posted
        lines {
          nodes {
            amount
            account {
              path
            }
          }
        }
      }
    }
  }
}
```

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "type": {
      "equalTo": "withdrawal"
    },
    "typeVersion": {
      "equalTo": "2"
    }
  }
}
```

To retrieve Ledger Entries of multiple typeVersions, use the `in` operator:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "type": {
      "equalTo": "withdrawal"
    },
    "typeVersion": {
      "in": ["2", "3"]
    }
  }
}
```

<a id="ledger-entries-filter-by-group"></a>

### Filter by group

Use `group` to filter Ledger Entries by [groups](https://fragment.dev/markdown/guides/group-ledger-entries.md):

```graphql title="FilterLedgerEntries"
query FilterLedgerEntries(
  $ledger: LedgerMatchInput!,
  $entriesFilter: LedgerEntriesFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerEntries(filter: $entriesFilter) {
      nodes {
        ik
        type
        posted
        groups {
          key
          value
        }
      }
    }
  }
}
```

Use the `equalTo` operator to find Ledger Entries that are in the specified group:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "group": {
      "equalTo": {
        "key": "department",
        "value": "sales"
      }
    }
  }
}
```

Use the `in` operator to find Ledger Entries that are in any of the specified groups:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "group": {
      "in": [{
        "key": "department",
        "value": "sales"
      },{
        "key": "department",
        "value": "inventory"
      }]
    }
  }
}
```

Use the `notEqualTo` operator to find Ledger Entries that are not in the specified group:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "group": {
      "notEqualTo": {
        "key": "department",
        "value": "sales"
      }
    }
  }
}
```

Use the `notIn` operator to find Ledger Entries that are not in any of the specified groups:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "group": {
      "notIn": [{
        "key": "department",
        "value": "sales"
      },{
        "key": "department",
        "value": "inventory"
      }]
    }
  }
}
```

Use the `keyEqualTo` operator to find Ledger Entries that are in a group with the specified group key:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "group": {
      "keyEqualTo": "department"
    }
  }
}
```

Use the `notKeyEqualTo` operator to find Ledger Entries that are not in any group with the specified group key:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "group": {
      "notKeyEqualTo": "department"
    }
  }
}
```

Use the `keyIn` operator to find Ledger Entries that are in any group with any of the specified group keys:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "group": {
      "keyIn": ["department", "priority"]
    }
  }
}
```

Use the `notKeyIn` operator to find Ledger Entries that are not in any group with any of the specified group keys:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "group": {
      "notKeyIn": ["department", "priority"]
    }
  }
}
```

<a id="ledger-entries-filter-by-tag"></a>

### Filter by tag

Use `tag` to filter Ledger Entries by [tags](https://fragment.dev/markdown/guides/store-metadata.md):

```graphql title="FilterLedgerEntries"
query FilterLedgerEntries(
  $ledger: LedgerMatchInput!,
  $entriesFilter: LedgerEntriesFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerEntries(filter: $entriesFilter) {
      nodes {
        ik
        type
        posted
        tags {
          key
          value
        }
      }
    }
  }
}
```

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "equalTo": {
        "key": "user_id",
        "value": "user-1"
      }
    }
  }
}
```

Use the `in` operator to find Ledger Entries that have any of the specified tags:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "in": [{
        "key": "user_id",
        "value": "user-1"
      },{
        "key": "user_id",
        "value": "user-2"
      }]
    }
  }
}
```

Use the `notEqualTo` operator to find Ledger Entries that do not have the specified tag:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "notEqualTo": {
        "key": "invoice-status",
        "value": "invoice-paid"
      }
    }
  }
}
```

Use the `notIn` operator to find Ledger Entries that do not have any of the specified tags:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "notIn": [{
        "key": "invoice-status",
        "value": "invoice-pending"
      },{
        "key": "invoice-status",
        "value": "invoice-cancelled"
      }]
    }
  }
}
```

Use the `contains` operator to find Ledger Entries that have a tag with a specific tag key and a partial match on the tag value. The filter matches when the tag value contains the specified tag value:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "contains": {
        "key": "user-id",
        "value": "merchant-"
      }
    }
  }
}
```

Use the `keyEqualTo` operator to find Ledger Entries that have a tag with the specified key:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "keyEqualTo": "user-id"
    }
  }
}
```

Use the `notKeyEqualTo` operator to find Ledger Entries that do not have a tag with a specified key:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "notKeyEqualTo": "user-id"
    }
  }
}
```

Use the `keyIn` operator to find Ledger Entries that have a tag with any of the specified tag keys:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "keyIn": ["user-id", "invoice-status"]
    }
  }
}
```

Use the `notKeyIn` operator to filter Ledger Entries that do not contain any of the specified keys:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "tag": {
      "notKeyIn": ["user-id", "invoice-status"]
    }
  }
}
```

<a id="ledger-entries-filter-by-reversal"></a>

### Filter by reversal

Use:
- `isReversal` to filter reversing Ledger Entries
- `isReversed` to filter reversed Ledger Entries

```graphql title="FilterLedgerEntries"
query FilterLedgerEntries(
  $ledger: LedgerMatchInput!,
  $entriesFilter: LedgerEntriesFilterSet!
) {
  ledger(ledger: $ledger) {
    ledgerEntries(filter: $entriesFilter) {
      nodes {
        ik
        type
        posted
        reversedBy {
          ik
          created
        }
        reverses {
          ik
          created
        }
      }
    }
  }
}
```

For all Ledger Entries, only one of `isReversal` or `isReversed` will ever be `true`. The following will return all reversing Ledger Entries:

```json title="FilterLedgerEntries Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "entriesFilter": {
    "isReversal": true
  }
}
```

<a id="ledger-entry-groups"></a>

## Ledger Entry Groups

See [Group Ledger Entries](https://fragment.dev/markdown/guides/group-ledger-entries.md) for more information about how to use Ledger Entry Groups.

<a id="ledger-entry-groups-lookup"></a>

### Lookup
Use the `ledger.ledgerEntryGroup` expansion to lookup a group by key and value.

```graphql title="GetLedgerEntryGroup"
query GetLedgerEntryGroup(
  $ledger: LedgerMatchInput!
  $entryGroup: EntryGroupMatchInput!
) {
  ledger(ledger: $ledger) {
    ledgerEntryGroup(ledgerEntryGroup: $entryGroup) {
      key
      value
      created
    }
  }
}
```

```json title="GetLedgerEntryGroup Variables"
{
  "entryGroup": {
    "key": "withdrawal",
    "value": "12345"
  },
  "ledger": {
    "ik": "quickstart-ledger"
  }
}
```

The response is:

```json title="GetLedgerEntryGroup Response"
{
  "data": {
    "ledger": {
      "ledgerEntryGroup": {
        "key": "withdrawal",
        "value": "12345",
        "created": "1969-06-16T13:32:00.000Z"
      }
    }
  }
}
```

<a id="ledger-entry-groups-list"></a>

### List

```graphql title="ListLedgerEntryGroups"
query ListLedgerEntryGroups(
  $ledger: LedgerMatchInput!
) {
  ledger(ledger: $ledger) {
    ledgerEntryGroups {
      nodes {
        key
        value
        created
      }
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="ListLedgerEntryGroups Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  }
}
```

The response is:

```json title="ListLedgerEntryGroups Response"
{
  "data": {
    "ledger": {
      "ledgerEntryGroups": {
        "nodes": [
          {
            "key": "withdrawal",
            "value": "12345",
            "created": "1969-06-16T13:32:00.000Z"
          },
          {
            "key": "withdrawal",
            "value": "54321",
            "created": "1969-06-21T02:56:05.000Z"
          }
        ],
        "pageInfo": {
          "endCursor": null,
          "hasNextPage": false,
          "hasPreviousPage": false,
          "startCursor": null
        }
      }
    }
  }
}
```

<a id="ledger-entry-groups-filter"></a>

### Filter

You can filter groups by `key`, `value`, `created`, and/or `balance`

```graphql title="ListLedgerEntryGroups"
query ListLedgerEntryGroups(
  $ledger: LedgerMatchInput!
  $filter: LedgerEntryGroupsFilterSet,
) {
  ledger(ledger: $ledger) {
    ledgerEntryGroups(filter: $filter) {
      nodes {
        key
        value
        created
      }
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="ListLedgerEntryGroups Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "key": {
      "equalTo": "withdrawal"
    },
    "created": {
      "before": "1969-06-20T00:00:00.000Z"
    }
  }
}
```

The response is:

```json title="ListLedgerEntryGroups Response"
{
  "data": {
    "ledger": {
      "ledgerEntryGroups": {
        "nodes": [
          {
            "key": "withdrawal",
            "value": "12345",
            "created": "1969-06-16T13:32:00.000Z"
          }
        ],
        "pageInfo": {
          "endCursor": null,
          "hasNextPage": false,
          "hasPreviousPage": false,
          "startCursor": null
        }
      }
    }
  }
}
```

The `balance` filter enables querying for group values where the balance of an account in the group matches a provided condition.

An example use-case is to find all groups with key "invoice" where a non-zero balance in a certain account represents an unpaid invoice.

When filtering by balance, a `key` must be provided, and a `created` filter cannot be used. A `value` filter is optional.
The `balance` filter uses the [LedgerEntryGroupBalanceFilterSet](https://fragment.dev/markdown/api-reference/ledger-types.md#filter-types-ledgerentrygroupbalancefilterset) API Type. An `account` field is required, and the `currency` and `ownBalance` fields are optional.

```graphql title="ListLedgerEntryGroups"
query ListLedgerEntryGroups(
  $ledger: LedgerMatchInput!
  $filter: LedgerEntryGroupsFilterSet,
) {
  ledger(ledger: $ledger) {
    ledgerEntryGroups(filter: $filter) {
      nodes {
        key
        value
        created
      }
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="ListLedgerEntryGroups Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "key": {
      "equalTo": "invoice"
    },
    "balance": {
      "account": {
        "path": {
          "equalTo": "liabilities/user-funds"
        }
      },
      "currency": {
        "equalTo": {
          "code": "USD"
        }
      },
      "ownBalance": {
        "ne": "0"
      }
    }
  }
}
```

<a id="links"></a>

## Links
<a id="links-lookup"></a>

### Lookup
Use the `link` query to retrieve a Link by ID:

```graphql title="GetLink"
query GetLink($link: LinkMatchInput!) {
  link(link: $link) {
    __typename
    name
  }
}
```

```json title="GetLink Variables"
{
  "link": {
    "id": "<Link ID>"
  }
}
```

The `__typename` field will indicate the type of of the [Link](https://fragment.dev/markdown/guides/sync-payments.md)

<a id="links-external-accounts"></a>

### External Accounts
Use the `link.externalAccounts` to list External Accounts represented by the Link.

```graphql title="GetLinkExternalAccounts"
query GetLinkExternalAccounts($link: LinkMatchInput!) {
  link(link: $link) {
    id
    externalAccounts {
      nodes {
        name
        id
        externalId
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="GetLinkExternalAccounts Variables"
{
  "link": {
    "id": "<Link ID>"
  }
}
```

The response is a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of External Accounts.

<a id="external-accounts"></a>

## External Accounts
<a id="external-accounts-lookup"></a>

### Lookup

Use the `externalAccount` query to retrieve an ExternalAccount by its ID at your external system:

```graphql title="GetExternalAccountByExternalIdAndLinkId"
query GetExternalAccount(
  $externalId: ID!
  $linkId: ID!
) {
  externalAccount(
    externalAccount: {
      externalId: $externalId
      linkId: $linkId
    }
  ) {
    name
    link {
      __typename
      id
      name
    }
  }
}
```

```json title="GetExternalAccountByExternalIdAndLinkId Variables"
{
  "externalId": "<External ID>",
  "linkId": "<Link ID>"
}
```

Or by its Fragment ID:

```graphql title="GetExternalAccountByFragmentID"
query GetExternalAccount($id: ID!) {
  externalAccount(externalAccount: { id: $id }) {
    name
    externalId
    linkId
    link {
      __typename
      id
      name
    }
  }
}
```

```json title="GetExternalAccountByFragmentID Variables"
{
  "id": "<Fragment External Account ID>"
}
```

<a id="external-accounts-txs"></a>

### Txs
Use the `externalAccount.txs` query to list Txs synced to an External Account:

```graphql title="ListExternalAccountTxs"
query ListExternalAccountTxs(
  $externalAccount: ExternalAccountMatchInput!
  $after: String
  $first: Int
  $before: String
) {
  externalAccount(
    externalAccount: $externalAccount
  ) {
    externalId
    link {
      __typename
      id
      name
    }
    txs(
      after: $after
      first: $first
      before: $before
    ) {
      nodes {
        externalId
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

You may optionally specify `before` and `after` to paginate the results and `first` to specify the page size.

```json title="ListExternalAccountTxs Variables"
{
  "externalAccount": {
    "externalId": "<External ID>",
    "linkId": "<Link ID>"
  },
  "after": "2023-07-01T00:00:00.000Z",
  "before": "2023-07-30T23:59:59.999Z",
  "first": 20
}
```

The response is a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of Txs.

<a id="external-accounts-linked-accounts"></a>

### Linked Accounts

Use the `externalAccount.ledgerAccounts` query to list Ledger Accounts linked to this External Account:

```graphql title="GetExternalAccountLinkedAccounts"
query GetExternalAccountLinkedAccounts(
  $externalAccount: ExternalAccountMatchInput!
) {
  externalAccount(
    externalAccount: $externalAccount
  ) {
    externalId
    name
    link {
      __typename
      id
      name
    }
    ledgerAccounts {
      nodes {
        path
        name
        type
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

```json title="GetExternalAccountLinkedAccounts Variables"
{
  "externalAccount": {
    "externalId": "<External ID>",
    "linkId": "<Link ID>"
  }
}
```

The response is a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of Ledger Accounts.

<a id="txs"></a>

## Txs
<a id="txs-lookup"></a>

### Lookup

Use the `tx` query to retrieve a Tx by its ID and Account ID at your external system:

```graphql title="GetTxByExternalIds"
query GetTx(
  $externalId: ID!
  $externalAccountId: ID!
  $linkId: ID!
) {
  tx(
    tx: {
      externalId: $externalId
      externalAccountId: $externalAccountId
      linkId: $linkId
    }
  ) {
    id
    description
    amount
    currency {
      code
    }
    externalId
    link {
      id
    }
    externalAccount {
      id
      externalId
    }
  }
}
```

```json title="GetTxByExternalIds Variables"
{
  "externalAccountId": "<External Account ID>",
  "external": "<External Tx ID>",
  "linkId": "<Link ID>"
}
```

Or by its Fragment ID:

```graphql title="GetTxByFragmentID"
query GetTx(
  $id: ID!
) {
  tx(
    tx: {
      id: $id
    }
  ) {
    id
    description
    amount
    currency {
      code
    }
    externalId
    link {
      id
    }
    externalAccount {
      id
      externalId
    }
  }
}
```

```json title="GetTxByFragmentID Variables"
{
  "id": "<Fragment ID>"
}
```

<a id="txs-unreconciled"></a>

### Unreconciled
Use the `ledgerAccount.unreconciledTx` query to list a Ledger Account's unreconciled Txs:

```graphql title="GetUnreconciledTxs"
query GetUnreconciledTxs(
  $ledgerAccount: LedgerAccountMatchInput!
  $after: String
  $first: Int
  $before: String
) {
  ledgerAccount(ledgerAccount: $ledgerAccount) {
    path
    unreconciledTxs(
      after: $after
      first: $first
      before: $before
    ) {
      nodes {
        id
        description
        amount
        currency {
          code
        }
        externalId
        link {
          id
        }
        externalAccount {
          id
          externalId
        }
      }
      pageInfo {
        hasNextPage
        endCursor
        hasPreviousPage
        startCursor
      }
    }
  }
}
```

You may optionally specify `before` and `after` to paginate the results and `first` to specify the page size.

```json title="GetUnreconciledTxs Variables"
{
  "ledgerAccount": {
    "path": "assets/banks/user-cash",
    "ledger": {
      "ik": "quickstart-ledger"
    }
  },
  "after": "2023-07-01T00:00:00.000Z",
  "before": "2023-07-30T23:59:59.999Z",
  "first": 20
}
```

The response is a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of Txs.

<a id="payments"></a>

## Payments

<a id="payments-lookup"></a>

### Lookup

Use the `payment` query to look up a Payment by its `ik`:

```graphql title="GetPayment"
query GetPayment($payment: PaymentMatchInput!) {
  payment(payment: $payment) {
    id
    ik
    type
    typeVersion
    status
    amount
    currency {
      code
    }
    parameters
    created
  }
}
```

```json title="GetPayment Variables"
{
  "payment": {
    "ik": "order-1024",
    "ledger": {
      "ik": "quickstart-ledger"
    }
  }
}
```

<a id="payments-list"></a>

### List

Use `ledger.payments` to list all Payments within a Ledger:

```graphql title="ListPayments"
query ListPayments(
  $ledger: LedgerMatchInput!
  $filter: PaymentsFilterSet
  $first: Int
  $after: String
) {
  ledger(ledger: $ledger) {
    payments(filter: $filter, first: $first, after: $after) {
      nodes {
        id
        ik
        type
        status
        amount
        currency {
          code
        }
        created
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}
```

```json title="ListPayments Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "first": 20
}
```

The response is a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of Payments.

<a id="payments-filter-by-status"></a>

### Filter by status

Use `status` to filter Payments by their `status`:

```graphql title="FilterPaymentsByStatus"
query ListPayments(
  $ledger: LedgerMatchInput!
  $filter: PaymentsFilterSet
  $first: Int
  $after: String
) {
  ledger(ledger: $ledger) {
    payments(filter: $filter, first: $first, after: $after) {
      nodes {
        id
        ik
        type
        status
        amount
        currency {
          code
        }
        created
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}
```

```json title="FilterPaymentsByStatus Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "status": {
      "equalTo": "settled"
    }
  }
}
```

To retrieve Payments in multiple statuses, use the `in` operator:

```json title="FilterPaymentsByStatus Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "status": {
      "in": ["needs_payment_method", "processing", "accepted"]
    }
  }
}
```

<a id="payments-filter-by-created"></a>

### Filter by created

Use `created` to filter Payments by their created timestamp between any two points in time:

```graphql title="FilterPaymentsByCreated"
query ListPayments(
  $ledger: LedgerMatchInput!
  $filter: PaymentsFilterSet
  $first: Int
  $after: String
) {
  ledger(ledger: $ledger) {
    payments(filter: $filter, first: $first, after: $after) {
      nodes {
        id
        ik
        type
        status
        amount
        currency {
          code
        }
        created
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}
```

```json title="FilterPaymentsByCreated Variables"
{
  "ledger": {
    "ik": "quickstart-ledger"
  },
  "filter": {
    "created": {
      "after": "2026-09-01T00:00:00Z",
      "before": "2026-09-02T00:00:00Z"
    }
  }
}
```

The `after` and `before` filters are inclusive, so use timestamps for the first and last moments of the period you're querying for.

<a id="schemas"></a>

## Schemas

<a id="schemas-lookup"></a>

### Lookup

Use the `schema` query to retrieve a Schema by its key:

```graphql title="GetSchema"
query GetSchema($schema: SchemaMatchInput!) {
  schema(schema: $schema) {
    key
    name
    latestVersion: version {
      created
      version
    }
    firstVersion: version(version: 1) {
      created
      version
    }
  }
}
```

When retrieving a Schema, use the `version` argument to query a specific version of the Schema. By default, the latest version is returned:

```json title="GetSchema Variables"
{
  "schema": {
    "key": "quickstart-schema"
  }
}
```

The JSON of a Schema version can be retrieved by querying the `json` field:

```graphql title="GetLatestSchemaJSON"
query GetLatestSchemaJSON(
  $schema: SchemaMatchInput!
) {
  schema(schema: $schema) {
    key
    name
    version {
      created
      version
      json
    }
  }
}
```

```json title="GetLatestSchemaJSON Variables"
{
  "schema": {
    "key": "quickstart-schema"
  }
}
```

<a id="schemas-list-versions"></a>

### List versions

Use the `schema.versions` query to query all the versions of your Schema:

```graphql title="ListSchemaVersions"
query ListSchemaVersions(
  $schema: SchemaMatchInput!
) {
  schema(schema: $schema) {
    key
    name
    versions {
      nodes {
        created
        version
        json
      }
    }
  }
}
```

The response is a [paginated](https://fragment.dev/markdown/guides/query-data.md#basics-pagination) list of your Schema's versions:

```json title="ListSchemaVersions Variables"
{
  "schema": {
    "key": "quickstart-schema"
  }
}
```

<a id="schemas-list-ledgers"></a>

### List Ledgers

Use the `schema.ledgers` query to list the Ledgers created off a Schema:

```graphql title="ListSchemaLedgers"
query ListSchemaLedgers(
  $schema: SchemaMatchInput!
) {
  schema(schema: $schema) {
    key
    name
    ledgers {
      nodes {
        ik
        name
        created
        balanceUTCOffset
      }
    }
  }
}
```

```json title="ListSchemaLedgers Variables"
{
  "schema": {
    "key": "quickstart-schema"
  }
}
```

<a id="schemas-migration-status"></a>

### Migration status

Fragment asynchronously migrates Ledgers when their Schema is updated. The current status of a Ledger's migration can be queried using the API, via `version.migrations`:

```graphql title="GetLedgerMigrationStatus"
query GetLedgerMigrationStatus(
  $schema: SchemaMatchInput!
) {
  schema(schema: $schema) {
    key
    name
    latestVersion: version {
      migrations {
        nodes {
          ledger {
            ik
            name
          }
          status
        }
      }
    }
  }
}
```

```json title="ListSchemaLedgers Variables"
{
  "schema": {
    "key": "quickstart-schema"
  }
}
```
