# Account Transactions
URL: https://www.quiltt.dev/api/transactions
Description: Learn how to fetch and manage Account Transactions through Quiltt's GraphQL API.
Navigation: api → transactions
Tags: API, Core Resources
Content Length: 10k characters

A **Transaction** in Quiltt represents financial activity associated with an [Account](/api/accounts). Account Transactions can include basic banking activities like deposits and withdrawals, as well as investment activities with associated securities and fees.

Metadata Note:

## Amounts and entry types

Quiltt normalizes transaction amounts to a single signed convention across every provider, so you interpret inflows and outflows the same way regardless of the upstream source.

The `amount` field is signed relative to the account:

- A **positive** `amount` is a `CREDIT` — money moving into the account, such as a deposit, refund, or incoming transfer.
- A **negative** `amount` is a `DEBIT` — money moving out of the account, such as a purchase, withdrawal, or outgoing transfer.

The `entryType` field mirrors the sign of `amount`: `CREDIT` for inflows and `DEBIT` for outflows. For example, a $56.78 card purchase has an `amount` of `-56.78` and an `entryType` of `DEBIT`, while a $1,500.00 paycheck deposit has an `amount` of `1500.00` and an `entryType` of `CREDIT`.

Info:
To return only inflows or only outflows, filter by `entryType` instead of by the sign of `amount`. Pass `filter: [entryType: CREDIT]` for inflows or `filter: [entryType: DEBIT]` for outflows.

For liability accounts such as credit cards and loans, the same rule applies: a `DEBIT` is a purchase or draw that increases what the account holder owes, and a `CREDIT` is a payment toward the balance. This matches the [balance sign convention](/api/balances#balance-values-by-account-type), where a negative balance is the amount owed.

## Schemas & Types

Profile GraphQL Note:

## GraphQL Queries

Transaction queries allow you to fetch data about specific transactions or lists of transactions associated with the Profile or an Account.

### `transaction`

Looks up a Transaction by its ID:

GraphQLRequest:

Query:
```graphql
query {
  transaction(id: "txn_11VgTOO9DR1vbAZxb6zBLdb") {
    id
    date
    description
    amount
    entryType
    status
    account [id
      name]
  }
}
```

  

Response:
```json
{
  "data": {
    "transaction": {
      "id": "txn_11VgTOO9DR1vbAZxb6zBLdb",
      "date": "2024-06-09",
      "description": "GROCERY STORE",
      "amount": -56.78,
      "entryType": "DEBIT",
      "status": "POSTED",
      "account": ["id": "acct_12tgD1YP33AwEvbdmSrcRY",
        "name": "Checking Account"]
    }
  }
}
```

### `transactions`

Info:
This query uses cursor-based pagination, based on the
[Relay Connection Specification](https://relay.dev/graphql/connections.htm).
Connection page size is capped at **100 records per request**. If you prefer
smaller pages, pass `first` and continue pagination with `pageInfo.endCursor`
until `hasNextPage` is `false`. See our
[Pagination guide](/api/graphql/pagination) for examples and best practices.

Lists and filters the Transactions associated with the Profile:

GraphQLRequest:

Query:
```graphql
query GetTransactions {
  transactions(
    first: 10,
    sort: DATE_DESC,
    filter: [status: [POSTED],
      entryType: DEBIT]
  ) {
    count
    edges {
      node {
        id
        date
        description
        amount
        entryType
        status
        account {name}
      }
    }
    pageInfo [hasNextPage
      endCursor]
  }
}
```

  

Response:
```json
{
  "data": {
    "transactions": {
      "count": 42,
      "edges": [
        {
          "node": {
            "id": "txn_11VgTOO9DR1vbAZxb6zBLdb",
            "date": "2024-06-09",
            "description": "GROCERY STORE",
            "amount": -56.78,
            "entryType": "DEBIT",
            "status": "POSTED",
            "account": ["name": "Checking Account"]
          }
        },
        ...
      ],
      "pageInfo": ["hasNextPage": true,
        "endCursor": "cursor_value_here"]
    }
  }
}
```

The `transactions` query supports various filtering options:

#### Filter by Amount

```graphql
query {
  transactions(filter: [amount_gte: 100,
    amount_lte: 500]) {
    count
    nodes [id
      amount
      description]
  }
}
```

#### Filter by Date Range

```graphql
query {
  transactions(filter: [date_gte: "2024-01-01",
    date_lte: "2024-01-31"]) {
    count
    nodes [id
      date
      amount]
  }
}
```

#### Filter by Account Type

```graphql
query {
  transactions(filter: [kind: [DEPOSITORY, CREDIT]]) {
    count
    nodes {
      id
      account [name
        kind]
    }
  }
}
```

## GraphQL Mutations

Transaction mutations allow you to update individual Transactions.

### `transactionUpdate`

Updates a Transaction with new metadata. This is useful for storing additional information about the Transaction:

GraphQLRequest:

Mutation:
```graphql
mutation TransactionUpdate {
  transactionUpdate(
    input: {
      id: "txn_11VgTOO9DR1vbAZxb6zBLdb",
      metadata: [category: "Groceries",
        notes: "Weekly shopping"]
    }
  ) {
    success
    record [id
      metadata]
  }
}
```

  

Response:
```json
{
  "data": {
    "transactionUpdate": {
      "success": true,
      "record": {
        "id": "txn_11VgTOO9DR1vbAZxb6zBLdb",
        "metadata": ["category": "Groceries",
          "notes": "Weekly shopping"]
      }
    }
  }
}
```

## REST operations

### Trigger a Transactions Refresh

API Endpoint - POST https://api.quiltt.io/v1/connections/{connectionId}/transactions/refresh:

Warning:
Transactions Refresh is currently in beta.
[Contact Quiltt Support](https://quiltt.io/support) to have it enabled for
your Environment.

Transactions stay current automatically through the
[Connection sync](/api/connections) flow. When you need the latest data on
demand — for example, right after a user asks you to check for a deposit that
just cleared — call the
[Trigger a Transactions Refresh](/api-reference/rest#tag/Connections) REST
endpoint.

The endpoint asks the underlying provider to fetch the newest transactions from
the connected institution.

Code Examples:

  ```sh
    API_URL='https://api.quiltt.io/v1'
    CONNECTION_ID='conn_14TJiFDKRJlPiBHuukUIlXZ'

    curl --request POST \
      --url "${API_URL}/connections/${CONNECTION_ID}/transactions/refresh" \
      --header 'Authorization: Bearer <API_SECRET_KEY>'
    ```
  ```http
    202 Accepted
    ```

A successful request returns a `202 Accepted` status code and triggers an
out-of-band transaction sync from the provider. The call is asynchronous: Quiltt
asks the provider to fetch fresh data and processes the result in the
background, rather than returning transactions in the response body.

If the refresh produces new, changed, or removed transactions, Quiltt fires the
`connection.synced.successful` webhook and the changes become available in
GraphQL. If nothing has changed since the last sync, no webhook fires — this
mirrors upstream providers, which only emit events when data changes.

Subscribe to sync events, as shown in the
[Syncing Transactions tutorial](/get-started/tutorials/transaction-sync), to
react when new data arrives instead of polling.

### What a refresh does and doesn't do

A Transactions Refresh requests the latest data the institution and aggregator
have available at that moment. It does **not** change how often the institution
or aggregator posts new data, and it does **not** guarantee that new
transactions are returned. If the bank has not posted or exposed anything new
since the last sync, the refresh produces no new data.

Two separate schedules govern when transactions update:

- Automatic sync: Quiltt triggers this on a recurring cadence. The
  institution and aggregator control how often it runs. It fetches the latest
  data available upstream.
- On-demand refresh: You trigger this by calling the endpoint, within the
  [refresh limits](#refresh-limits). It fetches the latest data available
  upstream.

Because both paths pull from the same upstream source, a refresh cannot surface
transactions the institution has not yet made available.

### How often transactions update

The upstream refresh cadence is set by the institution and aggregator, not by
Quiltt. Most institutions expose new transaction data once to a few times per
day — larger banks connected over OAuth tend to refresh more frequently, while
smaller institutions often update once per day.

Quiltt syncs with aggregators as frequently as possible, and at least daily, but
cannot make data appear faster than the institution posts it.

Triggering a refresh lets you request the latest available data on demand, but
the amount of new data you receive still depends on the institution's schedule.
If a Connection consistently lags behind what a user sees in their bank portal,
[contact Quiltt Support](https://quiltt.io/support) with the Connection ID.

### Refresh limits

You can refresh a given Connection at most **once every 4 hours**. A refresh
requested within that window returns `429 Too Many Requests`. While a refresh is
already running for a Connection, additional requests return `409 Conflict`
until it completes.

These per-Connection limits are separate from, and additional to, the
account-wide [REST API rate limits](/api#rate-limits).

### Response codes

- `202 Accepted`: The refresh was accepted and is processing in the background.
  Wait for a `connection.synced.successful` webhook, then fetch the updated
  transactions.
- `401 Unauthorized`: The request is missing a valid API Secret Bearer token.
  Confirm the `Authorization` header is present and the API key has not been
  revoked.
- `403 Forbidden`: The Connection is disconnected or in an error state. Resolve
  the Connection error before refreshing.
- `404 Not Found`: No Connection matches the provided ID. Confirm the URL
  contains a valid Connection ID.
- `409 Conflict`: A refresh is already in progress for this Connection. Wait for
  the in-progress refresh to finish before retrying.
- `429 Too Many Requests`: The Connection was refreshed too recently. Wait until
  the 4-hour window elapses before retrying.

## Remote Data

Transactions include remote data from various providers and enrichment services.
You can access this data through the `remoteData` field:

```graphql
query {
  transaction(id: "txn_11VgTOO9DR1vbAZxb6zBLdb") {
    id
    remoteData {
      ntropy {
        enrichment {
          response {
            categories {general}
            entities {
              counterparty [name
                logo
                website]
            }
          }
          timestamp
        }
      }
      mx {
        transaction {
          response [guid
            description
            originalDescription]
          timestamp
        }
      }
    }
  }
}
```

See the [Remote Data guide](/api/remote-data) for more information about accessing and working with provider-specific transaction data.