# Filtering and sorting

> Filter and sort API list endpoints with key.condition=value query parameters, match and order. Every condition and filterable field per resource.

List endpoints accept the same flat filter language in the query string: one query parameter per filter, combined with `match`, and sorted with `order` and `direction`. This page covers the syntax, the conditions for each field type, and every field you can filter and sort on, resource by resource.

## Syntax

A filter is a query parameter named `<key>.<condition>` with the value to compare against:

```text
GET /v2/emails?status.exact=bounced&created_at.after=2026-09-01
```

| Parameter | Description |
| --- | --- |
| `<key>.<condition>=<value>` | One filter. Add as many as you need, including several on the same key. |
| `match` | How filters combine. `all` (default) returns rows that match every filter. `or` returns rows that match at least one. |
| `order` | The key to sort by. Must be one of the sort keys of the endpoint. |
| `direction` | `asc` or `desc`. If you pass `order` without `direction`, results sort ascending. |

Without `order`, lists return the newest objects first.

Filters are combined with any dedicated parameters of the endpoint, such as `search` or `type`, using AND. `match` only controls how the `key.condition` filters combine with each other.

Unknown keys, conditions that don't fit the key's type, and values that can't be parsed (an invalid date, a non-number, an enum value that doesn't exist, or an empty value) are ignored rather than rejected. If a filter seems to have no effect, check its spelling.

### Legacy sort parameters

Some endpoints also accept `sort=<key>` with `order=asc` or `order=desc`. On [List contacts](/docs/api-reference/contacts/list/), [List templates](/docs/api-reference/templates/list/), [List automations](/docs/api-reference/automations/list/) and [List suppressions](/docs/api-reference/suppressions/list/), `order` only accepts `asc` or `desc`, so sort those lists with `sort=<key>&order=<direction>` instead of `order=<key>`. The legacy form works on every list endpoint.

## Conditions

Each key has a type, and each type accepts its own conditions.

| Condition | String | Number | Date | Boolean | Enum | Matches when the field… |
| --- | --- | --- | --- | --- | --- | --- |
| `exact` | Yes | Yes | Yes | Yes | Yes | equals the value. Strings compare case-sensitively. Dates compare the calendar day. |
| `not_exact` | Yes | Yes |  | Yes | Yes | doesn't equal the value. |
| `contains` | Yes |  |  |  |  | contains the value, ignoring case. |
| `not_contains` | Yes |  |  |  |  | doesn't contain the value, ignoring case. Empty fields match. |
| `starts_with` | Yes |  |  |  |  | starts with the value, ignoring case. |
| `ends_with` | Yes |  |  |  |  | ends with the value, ignoring case. |
| `gt`, `gte` | | Yes |  |  |  | is greater than (or equal to) the value. |
| `lt`, `lte` | | Yes |  |  |  | is less than (or equal to) the value. |
| `before` |  |  | Yes |  |  | is earlier than the value. |
| `after` |  |  | Yes |  |  | is later than the value. |
| `empty` | Yes | Yes | Yes |  |  | has no value. For strings, an empty string counts as empty. |
| `not_empty` | Yes | Yes | Yes |  |  | has a value. |

Value formats:

- **Dates.** Any ISO 8601 date or date-time, such as `2026-09-01` or `2026-09-01T14:30:00Z`. `before` and `after` are exclusive.
- **Booleans.** `true` or `1` mean true. Any other value means false.
- **Enums.** One of the values listed for the key below.
- **`empty` and `not_empty`.** The value is ignored, but the parameter needs one. Use `1`, for example `spam_score.empty=1`.

## Examples

Bounced or failed emails since September 1:

```text
GET /v2/emails?status.exact=bounced&status.exact=failed&match=or&date_from=2026-09-01
```

Because `match=or` applies to every filter in the request, you can't mix AND and OR. To combine a date range with alternative statuses on [List emails](/docs/api-reference/emails/list/), use the dedicated `date_from` parameter for the date as shown, since dedicated parameters always apply with AND.

Contacts at Acme whose `plan` custom field is `pro`, sorted by email:

```text
GET /v2/contacts?email.ends_with=%40acme.com&custom_fields.plan.exact=pro&sort=email&order=asc
```

Domains with a failing DKIM record, oldest first:

```text
GET /v2/domains?dkim_status.not_exact=ok&order=created_at&direction=asc
```

### URL encoding

Encode reserved characters in values: `+` as `%2B`, `&` as `%26`, `#` as `%23`, a space as `%20` and `@` as `%40`. An unencoded `+` in an address like `ada+news@example.com` is read as a space. With cURL, `-G` and `--data-urlencode` handle the encoding for you:

**cURL**

```bash
curl -G https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  --data-urlencode "to.exact=ada+news@example.com" \
  --data-urlencode "subject.contains=order #1042" \
  --data-urlencode "order=created_at" \
  --data-urlencode "direction=desc"
```

**Node.js**

```javascript
const params = new URLSearchParams({
  'to.exact': 'ada+news@example.com',
  'subject.contains': 'order #1042',
  order: 'created_at',
  direction: 'desc',
});

const response = await fetch(`https://api.emailit.com/v2/emails?${params}`, {
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const { data } = await response.json();
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://api.emailit.com/v2/emails",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    params={
        "to.exact": "ada+news@example.com",
        "subject.contains": "order #1042",
        "order": "created_at",
        "direction": "desc",
    },
)
data = response.json()["data"]
```

## Filterable fields

Unless a note says otherwise, every key in these tables is also a sort key.

### Emails

[List emails](/docs/api-reference/emails/list/) (`GET /emails`).

| Key | Type | Notes |
| --- | --- | --- |
| `to` | string | Recipient address. |
| `from` | string | Sender as sent, including any display name. |
| `subject` | string | |
| `status` | enum | `accepted`, `scheduled`, `delivered`, `loaded`, `clicked`, `attempted`, `bounced`, `failed`, `rejected`, `suppressed`, `received`, `complained`, `canceled`, `held` |
| `tag` | string | The email's tag. Sending through the API or SMTP doesn't set a tag at the moment. |
| `spam_score` | number | |
| `created_at` | date | Doesn't widen the default 14-day window. Use `date_from` for older emails. |
| `updated_at` | date | |
| `api_key_id` | string | The `key_…` ID of the API key that sent the email. |
| `sending_domain_id` | string | The `dom_…` ID of the sending domain. |

Also accepts `search`, `type` (`outbound` or `inbound`), `date_from` and `date_to`, plus the older `status`, `rcpt_to`, `mail_from`, `subject`, `api_key_id` and `sending_domain_id` parameters.

### Domains

[List domains](/docs/api-reference/domains/list/) (`GET /domains`).

| Key | Type | Notes |
| --- | --- | --- |
| `name` | string | |
| `created_at` | date | |
| `spf_status` | enum | `ok`, `missing`, `invalid` |
| `dkim_status` | enum | `ok`, `missing`, `invalid` |
| `return_path_status` | enum | `ok`, `missing`, `invalid` |

Also accepts `search` (domain name contains).

### API keys

[List API keys](/docs/api-reference/api-keys/list/) (`GET /api-keys`).

| Key | Type | Notes |
| --- | --- | --- |
| `name` | string | |
| `scope` | string | `full` or `sending`. |
| `type` | string | Credential type. Keys created in the dashboard or API are `api`. |
| `created_at` | date | |

Also accepts `search` (name contains).

### Audiences and subscribers

[List audiences](/docs/api-reference/audiences/list/) (`GET /audiences`) accepts `name` (string) and `created_at` (date), plus `search`.

[List subscribers](/docs/api-reference/audiences/subscribers/list/) (`GET /audiences/{id}/subscribers`):

| Key | Type | Notes |
| --- | --- | --- |
| `email` | string | The contact's email address. |
| `first_name` | string | |
| `last_name` | string | |
| `subscribed` | boolean | |
| `created_at` | date | When the contact joined the audience. |

Also accepts `search` (email, first or last name contains) and `subscribed=true|false`.

### Contacts

[List contacts](/docs/api-reference/contacts/list/) (`GET /contacts`) and [Export contacts](/docs/api-reference/contacts/export/).

| Key | Type | Notes |
| --- | --- | --- |
| `email` | string | |
| `first_name` | string | |
| `last_name` | string | |
| `name` | string | First and last name joined with a space. |
| `audiences` | string | The alphabetically first audience name of the contact. |
| `unsubscribed` | boolean | Filter only. |
| `created_at` | date | |
| `updated_at` | date | |
| `audience_id` | string | Filter only. Only `exact` and `not_exact`. The value is an audience ID (`aud_…`). |
| `custom_fields.<key>` | string | Filter only. Replace `<key>` with the custom field key, for example `custom_fields.company.contains=Acme`. Values compare as text. |

Sort contacts with `sort` set to `email`, `first_name`, `last_name`, `name`, `audiences`, `created_at` or `updated_at`, and `order` set to `asc` or `desc`. Also accepts `search` (alias `q`), `audience_id` and `unsubscribed`. The older `filter[audience_id]`, `filter[unsubscribed]` and `filter[custom_fields][<key>]` forms still work.

### Campaigns

[List campaigns](/docs/api-reference/campaigns/list/) (`GET /campaigns`).

| Key | Type | Notes |
| --- | --- | --- |
| `name` | string | |
| `subject` | string | |
| `status` | enum | `draft`, `scheduled`, `queued`, `sending`, `sent`, `archived` |
| `created_at` | date | |
| `sent_at` | date | |

Also accepts `search` (name or subject contains).

### Forms

[List forms](/docs/api-reference/forms/list/) (`GET /forms`).

| Key | Type | Notes |
| --- | --- | --- |
| `name` | string | |
| `type` | enum | `popup`, `full_page`, `flyout`, `embed`, `banner` |
| `status` | enum | `draft`, `live` |
| `created_at` | date | |

Also accepts `search` (name contains).

### Automations

[List automations](/docs/api-reference/automations/list/) (`GET /automations`).

| Key | Type | Notes |
| --- | --- | --- |
| `name` | string | |
| `status` | enum | Filter only. `draft`, `running`, `paused`, `stopped`, `archived` |
| `context` | string | Filter only. `contact`, `email` or `event`. |
| `created_at` | date | |

Sort with `sort` set to `name`, `created_at`, `updated_at` or `last_triggered_at`, and `order` set to `asc` or `desc`. Also accepts `filter[name]`, `filter[status]` and `filter[context]`.

[List runs](/docs/api-reference/automations/runs/) (`GET /automations/{id}/runs`) accepts `status` (string), `event` (string) and `created_at` (date).

### Templates

[List templates](/docs/api-reference/templates/list/) (`GET /templates`). Only published versions are listed.

| Key | Type | Notes |
| --- | --- | --- |
| `name` | string | |
| `alias` | string | |
| `editor` | string | Filter only. `html`, `text`, `dragit` or `tiptap`. |
| `subject` | string | Filter only. |
| `created_at` | date | |

Sort with `sort` set to `name`, `alias`, `created_at`, `updated_at` or `published_at`, and `order` set to `asc` or `desc`. Also accepts `filter[name]`, `filter[alias]` and `filter[editor]`.

### Suppressions

[List suppressions](/docs/api-reference/suppressions/list/) (`GET /suppressions`).

| Key | Type | Notes |
| --- | --- | --- |
| `email` | string | |
| `reason` | string | |
| `type` | string | |
| `created_at` | date | |
| `keep_until` | date | Filter only. |

Sort with `sort` set to `email`, `reason`, `type` or `created_at`, and `order` set to `asc` or `desc`. Also accepts `search` (alias `q`, email or reason contains).

Suppressions also accept a JSON filter builder in the `filters` parameter (alias `filter`). Pass a URL-encoded JSON object:

```json
{
  "match": "any",
  "rules": [
    { "field": "reason", "operator": "contains", "value": "bounce" },
    { "field": "type", "operator": "in", "value": "recipient,campaign" }
  ]
}
```

| Property | Description |
| --- | --- |
| `match` | `all` (default) or `any`. |
| `rules` | Up to 25 rules. Rules with an unknown field or operator are ignored. |
| `rules[].field` | `email`, `reason`, `type` or `created_at`. |
| `rules[].operator` | `equals`, `not_equals`, `contains`, `not_contains`, `starts_with`, `ends_with`, `greater_than`, `less_than`, `in`, `not_in`, `is_set` or `is_not_set`. |
| `rules[].value` | The value to compare. For `in` and `not_in`, a comma-separated list. Not needed for `is_set` and `is_not_set`. |

### Events

[List events](/docs/api-reference/events/list/) (`GET /events`).

| Key | Type | Notes |
| --- | --- | --- |
| `type` | string | The event type, such as `email.delivered`. |
| `created_at` | date | Any `created_at` filter replaces the default two-day window. |

Also accepts `type` as a comma-separated list of exact event types, and `include_data`.

### Webhooks

[List webhooks](/docs/api-reference/webhooks/list/) (`GET /webhooks`).

| Key | Type | Notes |
| --- | --- | --- |
| `name` | string | |
| `url` | string | |
| `enabled` | boolean | |
| `created_at` | date | |

Also accepts `search` (name or URL contains).

### Email verification lists

[List lists](/docs/api-reference/email-verifications/lists/list/) (`GET /email-verification-lists`) accepts `name` (string), `status` (string) and `created_at` (date), plus `search` and `status`.

[List results](/docs/api-reference/email-verifications/lists/results/) (`GET /email-verification-lists/{id}/results`):

| Key | Type | Notes |
| --- | --- | --- |
| `email` | string | |
| `status` | string | |
| `result` | string | For example `safe`, `invalid` or `disposable`. |
| `risk` | string | `low`, `medium` or `high`. |
| `created_at` | date | |

Also accepts `status` and `result`.

### DMARC reports

[List aggregate reports](/docs/api-reference/dmarc/list/) and [List forensic reports](/docs/api-reference/dmarc/forensic/).

| Key | Type | Notes |
| --- | --- | --- |
| `type` | string | `aggregate` or `forensic`. |
| `status` | string | |
| `org_name` | string | The organization that sent the report. |
| `created_at` | date | When Emailit received the report. |

Also accepts `type`, `status`, `org_name`, `from` and `to`. DMARC lists page with `limit` and `offset`. See [Pagination](/docs/api-reference/pagination/).

## Related

  - [Pagination](/docs/api-reference/pagination/): Page through list results.
  - [All endpoints](/docs/api-reference/endpoints/): Every endpoint and the scope it needs.

---
Source: https://emailit.com/docs/api-reference/filtering/
