# Filter approvals by type or status

```http
POST https://secure.yoprint.com/v1/api/store/{team_slug}/approvals/filter
```

- API version: v1
- Operation ID: `v1_public_approvals_filter`
- Section: Sales › [Approvals](https://developer.yoprint.com/reference/approvals.md)
- Web page: https://developer.yoprint.com/reference/approvals/v1-approvals-filter/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Lists approvals like `GET /v1/api/store/{team_slug}/approvals`, narrowed by `type` and `status`, with an optional sort. For example, everything still waiting on the customer: `status` `in` `pending`, `sent-to-customer`, `viewed-by-customer`.

Each filter is `{key, operator, value}` with `operator` `in` or `nin` and `value` a list. Several filters must all match. Send `page` in the body or the query string.

## Permission

Any member of the team. The list is not narrowed to orders you can see.

## Business rules

- `filters` is optional. If you send it, it can't be empty. Leaving it out returns every approval, like the list. Filter keys are `type` and `status` only.
- `value` must be a list, even for one value.
- Sort keys: `id`, `order_id`, `job_id`, `type`, `completed_at`, `created_at`, `status`; `direction` `asc` or `desc`.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.

## Request body

Content type `application/json`, optional.

Fields:

- `filters` (array of objects, optional): At least 1 item.
  - Each item:
    - `key` (string, required): One of: `"type"`, `"status"`.
    - `operator` (string, required): `in`: any of the values. `nin`: none of them. One of: `"in"`, `"nin"`.
    - `value` (array of strings, required): For `type`: `job`, `order`. For `status`: the approval statuses.
- `page` (integer, optional): Minimum 1.
- `sort` (array of objects, optional)
  - Each item:
    - `direction` (string, required): One of: `"asc"`, `"desc"`.
    - `key` (string, required): One of: `"id"`, `"order_id"`, `"job_id"`, `"type"`, `"completed_at"`, `"created_at"`, `"status"`.

### Example request

```bash
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/approvals/filter' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "filters": [
      {
        "key": "status",
        "operator": "in",
        "value": [
          "pending",
          "sent-to-customer",
          "viewed-by-customer"
        ]
      }
    ],
    "sort": [
      {
        "direction": "desc",
        "key": "created_at"
      }
    ]
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (array of objects, required)
  - Each item:
    - `approved_by` (string, optional): `user` when a team member completed it. Otherwise `customer`, even before anyone has approved it, and also when a Customer Portal contact approved it (Get an approval names the contact). One of: `"user"`, `"customer"`.
    - `approved_by_user` (string | null, optional): The hash id of the team member who completed it on the customer's behalf, if any.
    - `completed` (boolean, optional): True once the customer finished, whether they approved or asked for changes.
    - `completed_at` (string (date-time) | null, optional)
    - `created_at` (string (date-time), optional)
    - `customer_id` (integer | null, optional): A plain number for the customer, not a hash id: no operation takes it. Use `order_id` to reach the customer.
    - `customer_last_viewed_date` (string (date-time) | null, optional)
    - `customer_name` (string | null, optional)
    - `id` (string, optional)
    - `job_id` (string | null, optional): Job approvals only.
    - `job_name` (string, optional): An empty string for order approvals.
    - `job_scoped_id` (string, optional): The job number, such as `JOB-1001`. An empty string for order approvals.
    - `notes_from_customer` (string | null, optional)
    - `notes_to_customer` (string | null, optional)
    - `order_external_type` (string | null, optional)
    - `order_id` (string | null, optional)
    - `order_name` (string | null, optional)
    - `order_object_type` (string | null, optional): `sales_order` or `quote`. One of: `"sales_order"`, `"quote"`.
    - `order_quote` (boolean, optional): True when the approval is on a quote.
    - `order_scoped_id` (string, optional): The order or quote number.
    - `request_by` (string | null, optional): A team member's hash id, or null. Approvals created in the web app or through the API are null here: neither records who requested them.
    - `signature` (string | null, optional): The customer's signature, when they signed.
    - `status` (string, optional): `pending`: not sent yet. `sent-to-customer`: emailed. `viewed-by-customer`: the customer opened it. `need-changes`: the customer finished and asked for changes ("Review requested"). `completed`: approved. One of: `"pending"`, `"sent-to-customer"`, `"viewed-by-customer"`, `"need-changes"`, `"completed"`.
    - `type` (string, optional): `job`: artwork approval for one job's mockups. `order`: approval of the whole order. One of: `"job"`, `"order"`.
- `status` (integer, required)
- `success` (boolean, required)
- `pagination` (object, optional)
  - `count` (integer, required)
  - `currentPage` (integer, required)
  - `links` (object | array of any, required): Links to the neighbouring pages: `previous` and `next`, each present only when that page exists. An empty list, `[]`, when there is only one page.
    - `next` (string (uri), optional): The next page.
    - `previous` (string (uri), optional): The previous page.
  - `perPage` (integer, required)
  - `total` (integer, required)
  - `totalPages` (integer, required)

Example response:

```json
{
  "data": [
    {
      "approved_by": "customer",
      "approved_by_user": null,
      "completed": false,
      "completed_at": null,
      "created_at": "2026-11-03T09:30:00+00:00",
      "customer_id": 2001,
      "customer_last_viewed_date": null,
      "customer_name": "Northwind Apparel",
      "id": "Fi0zPeMlwKadEo",
      "job_id": "K6iF8n29iwOZnj",
      "job_name": "Front logo",
      "job_scoped_id": "JOB-1001",
      "notes_from_customer": null,
      "notes_to_customer": "Please check the logo size.",
      "order_external_type": null,
      "order_id": "V4keXwwxMQyXw7",
      "order_name": "Spring team shirts",
      "order_object_type": "sales_order",
      "order_quote": false,
      "order_scoped_id": "SO1001",
      "request_by": null,
      "signature": null,
      "status": "sent-to-customer",
      "type": "job"
    }
  ],
  "pagination": {
    "count": 1,
    "currentPage": 1,
    "links": [],
    "perPage": 50,
    "total": 1,
    "totalPages": 1
  },
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: `filters` is an empty list, a key or operator is not allowed, `value` is not a list, or a sort `key` or `direction` is not allowed (`validation_failed`, with the problem under `error.fields`). Fix: Send at least one `{key, operator, value}` with an allowed key, `in` or `nin`, and a list, or leave `filters` out. Write `direction` in lower case.

## Notes

- Without `sort`, the order of results is not defined. Send a sort, such as `created_at` `desc`, when you page.

## Related

- [List approvals](https://developer.yoprint.com/reference/approvals/v1-approvals-index.md): `GET /v1/api/store/{team_slug}/approvals`
