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

# List Transactions

> Page through your bill discoveries and payments

## Overview

Returns your Bill Payment transactions, newest first. Use it for reconciliation, for a history screen, and for finding a transaction when you have lost its identifier and its reference.

The list is scoped to your own account and to the environment of the key you send: a sandbox key never sees production transactions, and vice versa.

<Note>
  `data` is a **plain array** of transaction objects. The counts live in `meta`: `total`, `limit` and `offset`.
</Note>

## Query Parameters

<ParamField query="status" type="string">
  Filter by status. One of `PENDING`, `READY`, `PROCESSING`, `SUCCESS`, `FAILED`, `REFUNDED`, `UNKNOWN`.
</ParamField>

<ParamField query="partner" type="string">
  Filter by biller. One of `ADE`, `SONELGAZ`, `SEAAL`, `AADL`, `Algérie Télécom`.
</ParamField>

<ParamField query="from" type="string">
  Only transactions created on or after this instant. An ISO 8601 date or date-time, for example `2026-08-01` or `2026-08-01T00:00:00Z`.
</ParamField>

<ParamField query="to" type="string">
  Only transactions created on or before this instant. Same format as `from`.
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Page size, between 1 and 100.
</ParamField>

<ParamField query="offset" type="integer" default="0">
  How many transactions to skip. Zero or more.
</ParamField>

<Warning>
  There is no `ref` filter on this endpoint. To find a transaction by your own reference, use [Get Transaction by Reference](/en/api-reference/bill-payment/check-by-ref).
</Warning>

## Response

<ResponseField name="success" type="boolean" required>
  `true` when the page was returned.
</ResponseField>

<ResponseField name="data" type="array" required>
  An array of transaction objects, newest first. Each entry has exactly the shape documented on [Get Transaction by ID](/en/api-reference/bill-payment/check-by-id#response) — including the rule that `bills`, `selectedBill`, `receiptUrl`, `operationId` and `error` appear only in the statuses where they are meaningful.

  An empty array means no transaction matched.
</ResponseField>

<ResponseField name="meta" type="object" required>
  <Expandable title="properties">
    <ResponseField name="timestamp" type="string" required>
      Response time, ISO 8601 UTC.
    </ResponseField>

    <ResponseField name="total" type="integer" required>
      How many transactions match the filters in total, ignoring `limit` and `offset`.
    </ResponseField>

    <ResponseField name="limit" type="integer" required>
      The page size that was applied.
    </ResponseField>

    <ResponseField name="offset" type="integer" required>
      The offset that was applied.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="requestId" type="string" required>
  Correlation identifier, also sent as the `X-Request-Id` response header.
</ResponseField>

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -G https://billapi.oneclickdz.com/v3/bills/transactions \
    --data-urlencode "status=SUCCESS" \
    --data-urlencode "partner=ADE" \
    --data-urlencode "from=2026-08-01" \
    --data-urlencode "to=2026-08-31" \
    --data-urlencode "limit=50" \
    -H "X-Access-Token: YOUR_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const url = new URL("https://billapi.oneclickdz.com/v3/bills/transactions");
  url.searchParams.set("status", "SUCCESS");
  url.searchParams.set("partner", "ADE");
  url.searchParams.set("from", "2026-08-01");
  url.searchParams.set("to", "2026-08-31");
  url.searchParams.set("limit", "50");

  const response = await fetch(url, {
    headers: { "X-Access-Token": process.env.ONECLICKDZ_API_KEY },
  });

  const body = await response.json();

  if (!body.success) {
    throw new Error(`${body.error.code}: ${body.error.message}`);
  }

  console.log(`${body.data.length} of ${body.meta.total}`);
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.get(
      'https://billapi.oneclickdz.com/v3/bills/transactions',
      headers={'X-Access-Token': os.getenv('ONECLICKDZ_API_KEY')},
      params={
          'status': 'SUCCESS',
          'partner': 'ADE',
          'from': '2026-08-01',
          'to': '2026-08-31',
          'limit': 50
      }
  )

  body = response.json()

  if not body['success']:
      raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")

  print(f"{len(body['data'])} of {body['meta']['total']}")
  ```

  ```php PHP theme={null}
  <?php
  $query = http_build_query([
      'status'  => 'SUCCESS',
      'partner' => 'ADE',
      'from'    => '2026-08-01',
      'to'      => '2026-08-31',
      'limit'   => 50
  ]);

  $ch = curl_init("https://billapi.oneclickdz.com/v3/bills/transactions?$query");
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'X-Access-Token: ' . getenv('ONECLICKDZ_API_KEY')
  ]);

  $body = json_decode(curl_exec($ch), true);
  curl_close($ch);

  if (!$body['success']) {
      throw new Exception($body['error']['code'] . ': ' . $body['error']['message']);
  }

  echo count($body['data']) . ' of ' . $body['meta']['total'];
  ?>
  ```
</CodeGroup>

### Success Response

```json theme={null}
{
  "success": true,
  "data": [
    {
      "transactionId": "68b2f4c1a7d3e9f204c81a55",
      "ref": "disc-inv-2026-0042",
      "type": "payment",
      "status": "SUCCESS",
      "partner": "ADE",
      "account": { "reference": "0123456789012345678901234" },
      "selectedBill": {
        "billId": "sbx_bill_68b2f4c1a7d3e9f204c81a55_0",
        "amount": 443.39,
        "fee": 30.00,
        "label": "Facture ADE"
      },
      "total": 473.39,
      "currency": "DZD",
      "receiptUrl": "https://billapi.oneclickdz.com/v3/bills/transactions/68b2f4c1a7d3e9f204c81a55/receipt",
      "operationId": "op_7726351904",
      "createdAt": "2026-08-31T10:15:32.194Z",
      "updatedAt": "2026-08-31T10:15:41.902Z",
      "completedAt": "2026-08-31T10:15:41.902Z"
    }
  ],
  "meta": {
    "timestamp": "2026-08-31T11:02:14.508Z",
    "total": 137,
    "limit": 50,
    "offset": 0
  },
  "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
}
```

## Error Responses

<AccordionGroup>
  <Accordion title="400 — Validation error">
    **A filter value was not accepted.**

    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "ERR_VALIDATION",
        "message": "status must be one of: PENDING, READY, PROCESSING, UNKNOWN, SUCCESS, FAILED, REFUNDED",
        "details": [
          "status must be one of: PENDING, READY, PROCESSING, UNKNOWN, SUCCESS, FAILED, REFUNDED"
        ]
      },
      "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
    }
    ```

    Common causes: a status or partner outside the allowed set, a `from` or `to` that is not an ISO 8601 date, a `limit` above 100 or below 1, a negative `offset`.

    **What to do:** fix the query string. Values are case-sensitive.
  </Accordion>

  <Accordion title="401 — Missing or invalid access token">
    **The key was absent or rejected.**

    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "INVALID_ACCESS_TOKEN",
        "message": "The provided access token is invalid."
      },
      "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
    }
    ```

    **What to do:** verify the key with [Validate API Key](/en/api-reference/bill-payment/validate-key).
  </Accordion>

  <Accordion title="503 — Authentication or service unavailable">
    **We could not verify your key in time, or the API is in planned maintenance.**

    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "SERVICE_UNAVAILABLE",
        "message": "The service is temporarily unavailable. Please retry shortly."
      },
      "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
    }
    ```

    **What to do:** honour the `Retry-After` header (5 seconds) and retry. Listing is always safe to repeat.
  </Accordion>
</AccordionGroup>

## Paging through a period

`meta.total` is the count for the filters you sent, so you can page until you have seen all of it. Keep the page size modest and the window bounded.

```javascript theme={null}
async function* eachTransaction(filters) {
  let offset = 0;
  const limit = 100;

  for (;;) {
    const url = new URL("https://billapi.oneclickdz.com/v3/bills/transactions");
    for (const [key, value] of Object.entries(filters)) {
      url.searchParams.set(key, value);
    }
    url.searchParams.set("limit", String(limit));
    url.searchParams.set("offset", String(offset));

    const response = await fetch(url, {
      headers: { "X-Access-Token": process.env.ONECLICKDZ_API_KEY },
    });

    const body = await response.json();
    if (!body.success) throw new Error(body.error.code);

    for (const transaction of body.data) yield transaction;

    offset += body.data.length;
    if (offset >= body.meta.total || body.data.length === 0) return;
  }
}

// Every successful ADE payment in August
for await (const transaction of eachTransaction({
  status: "SUCCESS",
  partner: "ADE",
  from: "2026-08-01",
  to: "2026-08-31",
})) {
  console.log(transaction.transactionId, transaction.total);
}
```

<Note>
  New transactions are created while you page. For reconciliation, always bound the window with `from` and `to` so the result set cannot grow underneath you.
</Note>

## What the list contains

Both discoveries and payments appear here. `type` tells them apart:

* `type: "discovery"` — a lookup that has not been paid. Its `status` is `PENDING`, `READY` or `FAILED`.
* `type: "payment"` — a discovery that a payment was submitted against. Its `status` is `PROCESSING`, `SUCCESS`, `FAILED`, `REFUNDED` or `UNKNOWN`.

A transaction becomes a `payment` in place, keeping its `transactionId` and its original `ref`.

## Best Practices

<CardGroup cols={2}>
  <Card title="Bound every query" icon="calendar">
    Always send `from` and `to` for reconciliation. An unbounded list grows with your business.
  </Card>

  <Card title="Reconcile on SUCCESS and REFUNDED" icon="scale-balanced">
    Those two statuses are where money moved. `FAILED` never moved any.
  </Card>

  <Card title="Do not poll this endpoint" icon="ban">
    To follow one transaction, poll it by identifier. Listing repeatedly is slower and heavier for both sides.
  </Card>

  <Card title="Read meta.total" icon="list-ol">
    It is the count for your filters, and the only way to know whether another page exists.
  </Card>
</CardGroup>

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Get Transaction by ID" icon="id-card" href="/en/api-reference/bill-payment/check-by-id">
    The full transaction object
  </Card>

  <Card title="Get Transaction by Reference" icon="tag" href="/en/api-reference/bill-payment/check-by-ref">
    Look up by your own `ref`
  </Card>

  <Card title="Download Receipt" icon="file-arrow-down" href="/en/api-reference/bill-payment/get-receipt">
    Proof for a paid transaction
  </Card>

  <Card title="Receipts and Reconciliation" icon="scale-balanced" href="/en/bill-payment-guides/5-receipts-and-reconciliation">
    A daily reconciliation routine
  </Card>
</CardGroup>
