Back to home

Query parameters

The list endpoint (GET /m/{project-key}/{resource-name}) accepts a fixed set of query parameters. It always returns a bare JSON array — no wrapper object — with pagination metadata riding in response headers instead: X-Total-Count, X-Page, X-Limit, and a Link header (RFC 5988) carrying first/last/prev/next URLs.

Pagination

page (default 1) and limit (default 10, capped at 100 — a request for more just gets 100, it isn't rejected).

curl "https://mocklab.dev/m/demo7k2m9x/products?page=2&limit=20"

Sorting

sort names a field; order is asc (default) or desc.

curl "https://mocklab.dev/m/demo7k2m9x/products?sort=price&order=desc"

Sorting is stable — records with equal values on the sort field keep their relative order — and numeric-aware even for a formatted field like price: sorting by price compares 48.19 correctly against 120.00, not as text.

Filtering

Any query parameter that isn't one of the reserved names above (page, limit, sort, order, search) is treated as a filter on the field with that name. Plain field=value is an exact match; four suffixes cover the rest:

ParameterMatches
field=valueexact match
field_ne=valuenot equal
field_gte=valuegreater than or equal (numeric-aware)
field_lte=valueless than or equal (numeric-aware)
field_like=valuecase-insensitive substring match
curl "https://mocklab.dev/m/demo7k2m9x/products?inStock=true&price_gte=20&price_lte=100"

_gte/_lte strip a currency symbol or other formatting before comparing, so price_gte=20 correctly matches a price field returning "$48.19" — you don't need to know the field's exact formatting to filter on it numerically.

search matches if any field's value contains the term, case-insensitively — a quick way to find a record without knowing which field it's in.

curl "https://mocklab.dev/m/demo7k2m9x/products?search=vivid"

Invalid parameters

page, limit, and order are the three parameters with a strict, checkable shape — page and limit must be positive integers, order must be exactly asc or desc. Send something else and the request never reaches your data: it fails fast with 422 Validation failed and a body naming exactly which parameter was wrong. Everything else — sort, search, and every filter — has no fixed vocabulary to validate against, so a typo there (a filter on a field name that doesn't exist, for instance) isn't an error; it just matches nothing, since the server has no way to distinguish "wrong field name" from "a field that legitimately has no matching rows."

Combining parameters

All of the above compose in one request — filter, search, sort, and paginate together:

const params = new URLSearchParams({
  inStock: "true",
  price_gte: "20",
  sort: "price",
  order: "asc",
  page: "1",
  limit: "20",
});
const response = await fetch(`https://mocklab.dev/m/demo7k2m9x/products?${params}`);
const products = await response.json();
const totalCount = response.headers.get("X-Total-Count");
import { useQuery } from "@tanstack/react-query";

function InStockProducts({ page }) {
  const { data: products } = useQuery({
    queryKey: ["products", "in-stock", page],
    queryFn: async () => {
      const params = new URLSearchParams({
        inStock: "true",
        sort: "price",
        order: "asc",
        page: String(page),
        limit: "20",
      });
      const res = await fetch(`https://mocklab.dev/m/demo7k2m9x/products?${params}`);
      return res.json();
    },
  });

  return (
    <ul>
      {products?.map((product) => (
        <li key={product.id}>{product.title}</li>
      ))}
    </ul>
  );
}

One limit worth knowing up front: filtering, searching, and sorting only run on resources with 10,000 records or fewer. Above that, only pagination works — see How generation works for why, and how the response tells you when it's happened.