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

# Querying the RWS Connect API

> Every parameter the RWS Connect API supports: select, filter, group, aggregations, sorting and pagination

The RWS Connect API exposes your [RWS Connect](/en/core-concepts/rws-connect) tables as a REST API. Every query is a `GET` request to `https://connect.rwsintegration.com`, and what you retrieve is controlled entirely by query parameters.

The examples on this page use a fictional tenant `acme` with a table `employees` (columns `employee_id`, `name`, `department`, `city`, `salary`, `hired_at`, plus the [standard columns](#standard-columns)).

## Setting up the connection

RWS Connect uses a standard [Simple connection](/en/features/connections/api#simple):

| Field          | Value                                |
| -------------- | ------------------------------------ |
| Name           | `RWS Connect`                        |
| Type           | `API`                                |
| URL            | `https://connect.rwsintegration.com` |
| Base Path      | `/`                                  |
| Authentication | `Simple`                             |
| Headers        | `x-api-key`: the key provided by RWS |

## Request basics

Two parameters are required on every query:

| Parameter  | Value                                                   |
| ---------- | ------------------------------------------------------- |
| `database` | Your tenant name, provided during onboarding            |
| `table`    | The table name, agreed when the connector was requested |

```
GET https://connect.rwsintegration.com/?database=acme&table=employees
```

The response always has the same shape:

```json theme={null}
{
  "Items": [
    {
      "employee_id": "1042",
      "name": "Ana Souza",
      "department": "Sales",
      "city": "Manaus",
      "salary": 4200.0,
      "extracted_at": "2026-07-28 06:00:12.000",
      "extraction_date": "2026-07-28"
    }
  ],
  "Total": 1580
}
```

* **`Items`**: the records for the requested page. In your extract configuration, set **Datapoint Path in Response** to `Items`.
* **`Total`**: how many records match the query overall (across all pages). For grouped queries, the number of groups.

Without pagination parameters, a query returns the first **20** records.

## Column prefixes

A pipeline often combines several endpoints or source tables into one dataset. In that case each column is prefixed with the source it came from, and every record arrives as a single flat JSON object:

```json theme={null}
{
  "employees_employee_id": "1042",
  "employees_name": "Ana Souza",
  "contracts_position": "Sales Analyst",
  "contracts_start_date": "2024-03-01"
}
```

Filters, selects and all other parameters use the full prefixed column name (for example `filter[contracts_start_date][>=]=2026-01-01`). The examples on this page use a single-source table with unprefixed columns for brevity.

## Selecting columns

Project only the columns you need with `select[column]` (empty value):

```
?database=acme&table=employees&select[name]=&select[city]=
```

## Filtering

Filter with `filter[column][operator]=value`. Omitting the operator means equality:

```
?database=acme&table=employees&filter[city]=Manaus
?database=acme&table=employees&filter[salary][>=]=3000
```

Supported operators:

| Operator                  | Meaning                           |
| ------------------------- | --------------------------------- |
| `=` (default), `!=`, `<>` | Equal / not equal                 |
| `>`, `>=`, `<`, `<=`      | Comparison                        |
| `in`, `not in`            | Value in a list                   |
| `between`, `not between`  | Value inside a range (two values) |
| `like`, `not like`        | Pattern matching, `%` as wildcard |
| `ilike`, `not ilike`      | Case-insensitive pattern matching |
| `is`, `is not`            | Identity comparison               |

List and range operators take array values:

```
?database=acme&table=employees&filter[department][in][]=Sales&filter[department][in][]=Finance
?database=acme&table=employees&filter[hired_at][between][]=2026-01-01&filter[hired_at][between][]=2026-06-30
```

Multiple filters combine with AND:

```
?database=acme&table=employees&filter[city]=Manaus&filter[salary][>=]=3000
```

<Note>
  When calling the API by hand (for example with `curl`), remember to URL-encode special characters: `%` in a `like` pattern becomes `%25`. In the platform's extract configuration, query parameter values are encoded automatically.
</Note>

### Filtering by date and time

Prefix the column name with `timestamp_` to compare as date/time instead of text. The prefix only exists in the filter; the column keeps its real name in the response:

```
?database=acme&table=employees&filter[timestamp_extracted_at][>=]=2026-07-01
```

This is where [dynamic parameters](/en/features/extract/dynamic-parameters) shine. For example, a daily integration that only reads yesterday's snapshot:

```
filter[timestamp_extraction_date][>=]={{ now.subtract(1, days).format(YYYY-MM-DD) }}
```

## Sorting

```
?database=acme&table=employees&sort[name]=asc
?database=acme&table=employees&sort[salary]=desc
```

## Pagination

The API paginates with `page[size]` and `page[number]` (starting at 1):

```
?database=acme&table=employees&page[size]=100&page[number]=2
```

In your extract configuration this maps directly onto [Simple pagination](/en/features/extract/pagination#simple-pagination):

| Field                  | Value          |
| ---------------------- | -------------- |
| Pagination Type        | `Simple`       |
| Page size parameter    | `page[size]`   |
| Page size value        | e.g. `100`     |
| Initial page parameter | `page[number]` |
| Initial page value     | `1`            |
| Pagination end type    | `Object`       |

## Grouping and aggregations

Group with `group[column]` (or the shorthand `select[column]=group`, which also returns the column) and aggregate with `select[column]=<function>`:

```
?database=acme&table=employees&select[city]=group&select[salary]=sum
```

```json theme={null}
{
  "Items": [
    { "city": "Manaus", "salary": 182000.0 },
    { "city": "Belém", "salary": 97000.0 }
  ],
  "Total": 2
}
```

| Aggregation    | Meaning                          |
| -------------- | -------------------------------- |
| `sum`          | Sum of the column per group      |
| `sum_distinct` | Sum of distinct values per group |
| `avg`          | Average per group                |
| `min` / `max`  | Minimum / maximum per group      |
| `count`        | Count per group                  |

For grouped queries, `Total` is the number of groups.

## Latest record per key

RWS Connect tables preserve history: every pipeline run adds a snapshot. The `over_` filter answers the most common question about such tables: *"give me only the newest record for each key."*

```
?database=acme&table=employees&filter[over_employee_id][extracted_at]=first
```

This returns one record per `employee_id`: the one with the highest `extracted_at` (`first` keeps the newest, `last` keeps the oldest).

The syntax is `filter[over_<columns>][<sort column>]=first|last`. Combine grouping columns with `_and_`:

```
?database=acme&table=employees&filter[over_employee_id_and_department][extracted_at]=first
```

<Warning>
  * Only one `over_` filter is allowed per query.
  * `over_` cannot be combined with `select`, `group` or aggregation parameters.
  * The winning record per key is chosen **before** other filters are applied. `filter[over_employee_id][extracted_at]=first` plus a date filter means "take each employee's newest record overall, then keep it only if it passes the date filter", not "the newest record within the date range".
</Warning>

### Sums per key

To total a column per key while still returning one record per key, use `select[column]=sum_over` with `over_group` (required):

```
?database=acme&table=employees&select[salary]=sum_over&over_group=department
```

## Standard columns

Every RWS Connect table carries these columns, useful for filtering snapshots:

| Column                         | Meaning                                           |
| ------------------------------ | ------------------------------------------------- |
| `extracted_at`                 | Timestamp when the record was extracted           |
| `extraction_date`              | Date of the pipeline run that produced the record |
| `extract_start_date_parameter` | Start of the date window the run extracted        |
| `extract_end_date_parameter`   | End of the date window the run extracted          |

## Behavior and limits

* Results for identical queries may be served from a cache for up to **10 minutes**
* Default page size is **20** records
* Only one `over_` window filter per query, and it cannot be combined with `select`, `group` or aggregations

## Next steps

<CardGroup cols={2}>
  <Card title="Guide: Extract from RWS Connect" icon="cloud-arrow-down" href="/en/guides/rws-connect">
    Build a working integration on top of a Connect table
  </Card>

  <Card title="Dynamic Parameters" icon="brackets-curly" href="/en/features/extract/dynamic-parameters">
    Inject dates and variables into your filters
  </Card>
</CardGroup>
