---
title: "List Testset Rows"
method: GET
path: "/api/testsets/{testset_id}/rows/"
tags: ["testsets"]
---

# List Testset Rows

`GET /api/testsets/{testset_id}/rows/`

Mixin for views that need method-level permission enforcement.

Supports two approaches for defining permissions:

1. Auto-generation (Recommended - DRY):
    Set permission_resource to auto-generate CRUD permissions based on HTTP methods:

    class MyView(PermissionMapMixin, JWTAndAPIKeyAuthenticationViewMixin, RetrieveUpdateDestroyAPIView):
        permission_resource = Resources.LOG
        # Auto-generates:
        # GET -> log:read
        # PATCH -> log:update
        # DELETE -> log:delete

    Override specific methods via permission_map (always use constants):
    class MyView(PermissionMapMixin, ...):
        permission_resource = Resources.LOG
        permission_map: PermissionMap = {
            "GET": None,  # Override: no permission required for GET
            "POST": make_permission(Resources.LOG, CRUDActions.READ),  # POST acts as read
        }

2. Explicit mapping (for non-CRUD or complex cases - always use constants):
    class MyView(PermissionMapMixin, JWTAndAPIKeyAuthenticationViewMixin, APIView):
        permission_map: PermissionMap = {
            "GET": make_permission(Features.PROXY, Actions.ACCESS),
            "POST": make_permission(Features.PLAYGROUND, Actions.ACCESS),
        }

3. Dynamic logic (most flexible):
    def get_required_permission(self, method: str) -> str | None:
        if self.kwargs.get('public'):
            return None
        return "dataset:read"

Notes:
- permission_map acts as an override when permission_resource is set
- If neither is defined, no permission check is performed (backward compatible)
- HasJWTPermission automatically enforces permissions when defined

## Path parameters

- `testset_id` string, required

## Query parameters

- `page` integer
- `page_size` integer

## Headers

- `Authorization` string, required

## Response `200`

- PaginatedPublicTestsetRowListList
  - `count` integer, required
  - `next` string, uri, nullable
  - `previous` string, uri, nullable
  - `total_count` integer
  - `current_filters` FilterParamDictPydantic — Pydantic model for FilterParamDict. A dictionary that maps metric names to their filter parameters. Each key is a metric name (str), and each value can be: - A single MetricFilterParamPydantic (one condition) - A List[MetricFilterParamPydantic] (multiple conditions for same metric) - A FilterBundlePydantic (nested filter bundle with connector) Note: Uses extra="allow" for dynamic metric name fields. The __pydantic_extra__ annotation tells Pydantic what types to expect for extra fields, and generates typed additionalProperties in JSON Schema.
  - `filters_data` PaginatedPublicTestsetRowListListFiltersData
  - `results` PublicTestsetRowList[], required
    - `row_index` number, double
    - `height` integer, nullable
    - `row_data` unknown
    - `testset_sheet` string, required

---

[API](https://skmtc.net/keywordsai/apis/api-reference.md) · [All operations](https://skmtc.net/keywordsai/apis/api-reference/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/keywordsai/api-reference/versions/c26d550029f8/schema)
