---
updatedAt: 2026-05-21T15:12:22.000Z
agentTools:
  projectIndex: https://developer.bill.com/llms.txt
---

# Search operations with lists

When you request a list of objects with the BILL v3 API, you can perform a range of operations in your requests. This includes filtering, sorting, and pagination. In your GET request, add all search operations as query parameters.

## Filter operation

Set the field name, operator, and value in your list filters as query parameters. Both simple and compound filtering is available.

The format is `filters={field_01}:{op}:{value},{field_02}:{op}:{value}`.

### Operators

A range of operators are available for you to filter with. See <Anchor label="Filterable fields" target="_blank" href="doc:filterable-fields">Filterable fields</Anchor> for information about available fields and related operators.

| Operator value | Name                  | Example                                              |
| :------------- | :-------------------- | :--------------------------------------------------- |
| `eq`           | Equal                 | `filters=accountType:eq:BUSINESS`                    |
| `ne`           | Not equal             | `filters=billCurrency:ne:USD`                        |
| `gt`           | Greater than          | `filters=createdTime:gt:"2026-12-30T00:00:00.000Z"`  |
| `gte`          | Greater than or equal | `filters=updatedTime:gte:"2026-12-30T00:00:00.000Z"` |
| `lt`           | Less than             | `filters=createdTime:lt:"2026-12-30T00:00:00.000Z"`  |
| `lte`          | Less than or equal    | `filters=updatedTime:lte:"2026-12-30T00:00:00.000Z"` |
| `in`           | In                    | `filters=invoiceCurrency:in:"USD,CAD"`               |
| `nin`          | Not in                | `filters=accountType:nin:"NONE,PERSON"`              |
| `sw`           | Starts with           | `filters=name:sw:"Hap"`                              |

> 👍 Options for filtering with `createdTime` and `updatedTime`
>
> For filtering with `createdTime` and `updatedTime`, you can set a range of ISO 8601 date-time values.
>
> * `yyyy-MM-dd'T'HH:mm:ss.SSSX`
> * `yyyy-MM-dd'T'HH:mm:ss.SSS`
> * `yyyy-MM-dd'T'HH:mm:ss`
> * `yyyy-MM-dd'T'HH:mm`
> * `yyyy-MM-dd`

### Sample request

In this cURL example, the filter is set for all vendors created in September 2026. A compound filter is set with `filters=createdTime:gte:"2026-09-01T00:00:00.000Z",createdTime:lt:"2026-10-01T00:00:00.000Z"`.

```curl
curl --request GET \
--url 'https://gateway.stage.bill.com/connect/v3/vendors?filters=createdTime:gte:"2026-09-01T00:00:00.000Z",createdTime:lt:"2026-10-01T00:00:00.000Z"' \
--header 'content-type: application/json' \
--header 'devKey: {developer_key}' \
--header 'sessionId: {session_id}'
```

## Sort operation

Set the field name and sort order as query parameters. You can sort in the ascending (`asc`) or descending (`desc`) order. The default sorting order is ascending. Both simple and compound sorting is available.

The format is `sort={field_01}:{sort_order},{field_02}:{sort_order}`.

> 👍 Sorting order
>
> Sorting occurs in the specified order.

| Sorting examples                  | Description                                                                          |
| :-------------------------------- | :----------------------------------------------------------------------------------- |
| `sort=dueDate:asc`                | Sort by `dueDate` in the ascending order                                             |
| `sort=dueDate:desc`               | Sort by `dueDate` in the descending order                                            |
| `sort=dueDate,fundingAmount:desc` | Sort by `dueDate` in the ascending order and `fundingAmount` in the descending order |

See <Anchor label="Sortable fields" target="_blank" href="doc:sortable-fields">Sortable fields</Anchor> for information about fields you can sort with.

### Sample request

In this cURL example, vendors are sorted by `createdTime` in the descending order.

```curl
curl --request GET \
--url 'https://gateway.stage.bill.com/connect/v3/vendors?sort=createdTime:desc' \
--header 'content-type: application/json' \
--header 'devKey: {developer_key}' \
--header 'sessionId: {session_id}'
```

## Pagination

When you perform a search, you get a maximum of 100 results with one API request. For example, you get a maximum of 100 bills with one `GET /v3/bills` request.

When your search response has over 100 results, the results are paginated. In this case, the response includes `nextPage` and `prevPage` values for you to navigate between the pages of results. The `nextPage` and `prevPage` values uniquely represent each page of results based on your search.

### Sample request 01: Get first page of 5 results

In this cURL example, vendors are filtered by `billCurrency` and also sorted by `createdTime` in the descending order. In addition, the `max` query parameter is set as `5` to get 5 results per page.

The query parameters are set as `filters=billCurrency:eq:USD&sort=createdTime:desc&max=5`.

```curl
curl --request GET \
--url 'https://gateway.stage.bill.com/connect/v3/vendors?filters=billCurrency:eq:USD&sort=createdTime:desc&max=5' \
--header 'content-type: application/json' \
--header 'devKey: {developer_key}' \
--header 'sessionId: {session_id}'
```

### Response 01

In the response, the first 5 results are available. A `nextPage` value is available for you to get the next page of results in a subsequent request.

```json
{
  "nextPage": "{nextPage_value}",
  "results": [
    {
      // result 01
    },
    
    ...
    
    {
      // result 05
    }
  ]
}
```

### Sample request 02: Get next page of 5 results

In this cURL example, the next page of 5 results are requested. The `page` query parameter is set as the `nextPage` value from the previous response. Since `nextPage` value uniquely represents a page of results based on the search, do not set any `filters` and `sort` parameters.

> 👍 The `max` value can be updated per page
>
> You can change the `max` value in your subsequent request. For example, you can request a next page of 15 results with `max=15`.

The query parameters are set as `?page={nextPage_value}&max=5`.

```curl
curl --request GET \
--url 'https://gateway.stage.bill.com/connect/v3/vendors?page={nextPage_value}&max=5' \
--header 'content-type: application/json' \
--header 'devKey: {developer_key}' \
--header 'sessionId: {session_id}'
```

### Response 02

In the response, the next 5 results are available. Both `nextPage` and `prevPage` values are available for you to navigate between pages of results in a subsequent request.

```json
{
  "nextPage": "{nextPage_value}",
  "prevPage": "{prevPage_value}",
  "results": [
    {
      // result 06
    },
    
    ...
    
    {
      // result 10
    }
  ]
}
```

## Export to CSV

In this section, we showcase an example for exporting list response values to CSV. In this example, we list all bills created a day earlier. For each bill in the list response, we then export specific bill details to a CSV file.

```python Export to CSV (Python)
import requests, json, csv
from datetime import date, timedelta

# Set your session ID & developer key
session_id = "set_your_session_id"
developer_key = "set_your_developer_key"

headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "sessionId": session_id,
    "devKey": developer_key
}

# List bills created each day
yesterday = date.today() - timedelta(days=1)
yesterday = yesterday.strftime("%Y-%m-%dT%H:%M:%S.%jZ")

today = date.today()
today = today.strftime("%Y-%m-%dT%H:%M:%S.%jZ")

response_json = []
max_value = 20
filterquery = "createdTime:gte:\"" + yesterday + "\",createdTime:lt:\"" + today + "\""

listbills_url = f'https://gateway.stage.bill.com/connect/v3/bills?max={max_value}&filters={filterquery}'
listbills_response = requests.get(listbills_url, headers=headers)

nextpage_value = json.loads(listbills_response.text)['nextPage']
if listbills_response.text != '[]':
    results = json.loads(listbills_response.text)['results']
    response_json.extend(results)

while True:
    listmorebills_url = f'https://gateway.stage.bill.com/connect/v3/bills?max={max_value}&page={nextpage_value}'
    listmorebills_response = requests.get(listmorebills_url, headers=headers)
    if "nextPage" in json.loads(listmorebills_response.text):
        nextpage_value = json.loads(listmorebills_response.text)['nextPage']
        results = json.loads(listmorebills_response.text)['results']
        response_json.extend(results)
    else:
        break

fields_to_export = ['id', 'vendorId', 'dueDate', 'createdTime']

with open('data.csv', 'w', newline='') as csv_file:
    writer = csv.DictWriter(csv_file, fieldnames=fields_to_export)
    writer.writeheader()
    for json_obj in response_json:
        row_data = {field: json_obj[field] for field in fields_to_export}
        writer.writerow(row_data)
```
```node Export to CSV (Node.js)
// Requires "type": "module" in your package.json
import fetch from 'node-fetch';
import { createObjectCsvWriter } from 'csv-writer';
import { format, subDays } from 'date-fns';

// Set your session ID & developer key
const session_id = "set_your_session_id";
const developer_key = "set_your_developer_key";

// Headers for the API requests
const headers = {
  "Accept": "application/json",
  "Content-Type": "application/json",
  "sessionId": session_id,
  "devKey": developer_key
};

// Set the date range
const yesterday = format(subDays(new Date(), 1), 'yyyy-MM-dd');
const today = format(new Date(), 'yyyy-MM-dd');

// Set the filter query
const max_value = 20;
const filterquery = `createdTime:gte:"${yesterday}",createdTime:lt:"${today}"`;

let listbills_url = `https://gateway.stage.bill.com/connect/v3/bills?max=${max_value}&filters=${filterquery}`;

let response_json = [];

async function fetchBillsAndWriteCSV() {
  try {
    // Step 1: Get the first page of bills
    let listbills_response = await fetch(listbills_url, {
      method: 'GET',
      headers: headers
    });
    let listbills_result = await listbills_response.json();

    // Print the response
    console.log("API Response:", JSON.stringify(listbills_result, null, 2));

    // Check if the response contains results
    if (listbills_result.results && listbills_result.results.length > 0) {
      console.log("Results found:", listbills_result.results.length);
      response_json.push(...listbills_result.results);

      let nextpage_value = listbills_result.nextPage;

      // Step 2: Continue getting a list of bills if there is a next page
      while (nextpage_value) {
        const listmorebills_url = `https://gateway.stage.bill.com/connect/v3/bills?max=${max_value}&page=${nextpage_value}`;
        const listmorebills_response = await fetch(listmorebills_url, {
          method: 'GET',
          headers: headers
        });
        const listmorebills_result = await listmorebills_response.json();

        // Print the next page of responses
        console.log("Next page response:", JSON.stringify(listmorebills_result, null, 2));

        if (listmorebills_result.results) {
          response_json.push(...listmorebills_result.results);
        }

        nextpage_value = listmorebills_result.nextPage || null;
      }
    } else {
      console.log("No results found in the initial API request.");
    }

    // Step 3: Write the list of bills in a CSV file
    const fields_to_export = ['id', 'vendorId', 'dueDate', 'createdTime'];
    const csvWriter = createObjectCsvWriter({
      path: 'data.csv',
      header: fields_to_export.map(field => ({ id: field, title: field }))
    });

    await csvWriter.writeRecords(response_json.map(json_obj => {
      const row_data = {};
      fields_to_export.forEach(field => {
        row_data[field] = json_obj[field];
      });
      return row_data;
    }));

    console.log("CSV file 'data.csv' has been written successfully.");

  } catch (error) {
    console.error("Error occurred:", error.message);
  }
}

// Call the fetchBillsAndWriteCSV() function
fetchBillsAndWriteCSV();
```

<br />

<br />