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

# Querying & reporting

> Read and filter donations, memberships, and transactions with server-side filters.

You can query financial data directly, with server-side filtering, instead of fetching whole transaction bundles and filtering on your side. This is the recommended way to build reports and sync data into external tools.

## Endpoints

| Endpoint                             | Returns                                                                          |
| :----------------------------------- | :------------------------------------------------------------------------------- |
| `GET /v1/transactions`               | Individual transactions (the payment legs), filterable                           |
| `GET /v1/transactions/{id}`          | A single transaction, with its contact, status and bundle                        |
| `GET /v1/contacts/{id}/transactions` | A contact's full transaction history plus lifetime donation totals (`total_don`) |
| `GET /v1/donations`                  | Donations directly, filterable                                                   |
| `GET /v1/memberships`                | Memberships directly, filterable                                                 |
| `GET /v1/transaction_bundles`        | Bundles, now filterable by creation date (`created_from` / `created_to`)         |

## Filtering

All filters are optional and combined with **AND**. Amounts are in **cents**; dates are **ISO 8601** (e.g. `2026-04-01T00:00:00Z`).

**`GET /v1/donations`**

| Parameter                    | Filter                                                                               |
| :--------------------------- | :----------------------------------------------------------------------------------- |
| `date_from`, `date_to`       | Donation date range                                                                  |
| `created_from`, `created_to` | Record creation date range                                                           |
| `amount_min`, `amount_max`   | Amount range (cents)                                                                 |
| `contact_id`                 | One or more contacts (repeat or comma-separate)                                      |
| `donation_price_id`          | One or more donation prices                                                          |
| `sort`, `order`              | `sort` ∈ `date` (default), `created_at`, `amount`; `order` ∈ `desc` (default), `asc` |

**`GET /v1/memberships`** — same as donations, with `start_from`/`start_to`, `end_from`/`end_to` instead of `date_*`, `membership_price_id` instead of `donation_price_id`, and `sort` ∈ `start_date` (default), `end_date`, `created_at`, `amount`.

**`GET /v1/transactions`** — `date_from`/`date_to`, `created_from`/`created_to`, `amount_min`/`amount_max`, `status_id` (repeat for several), `payment_method_kind`, `code_campaign`, `external_transaction_id`, `sort` ∈ `created_at` (default), `date`, `amount`.

## Pagination

List endpoints accept `limit` (max **1000**) and `offset`, and return a top-level `total` you can use directly as a count.

```bash theme={"system"}
GET /v1/donations?date_from=2026-04-01T00:00:00Z&date_to=2026-04-30T23:59:59Z&limit=1000&offset=0
```

## Reporting recipes

A few common monthly metrics, all from a single donations query for the month:

```bash theme={"system"}
GET /v1/donations?date_from=2026-04-01T00:00:00Z&date_to=2026-04-30T23:59:59Z&limit=1000
```

| Metric                  | How                                   |
| :---------------------- | :------------------------------------ |
| **Number of donations** | the `total` field of the response     |
| **Donation total**      | sum of `amount` across `data` (cents) |
| **Unique donors**       | distinct `contact_id` across `data`   |

**First-time (new) donors** — Qomon has no "first donated" field, so determine it from donation history:

* **Recommended:** keep a running set of all donor `contact_id`s you've already seen. Each month, fetch that month's donors and treat any not already in your set as new, then add them. One call per month.
* **Stateless alternative:** for each donor that month, check whether they donated earlier with `GET /v1/donations?contact_id=<id>&date_to=<month_start>&limit=1`. An empty result (`total` = 0) means they are a first-time donor. This makes one call per donor.

<Info>
  Please be gentle with the API: there is a limit of **10 requests/second** per organization. For a monthly job that is plenty — add a small delay (\~150 ms) between calls rather than firing them all at once. On a `429 Too Many Requests`, wait the seconds given in the `Retry-After` header and retry.
</Info>
