---
title: "GET /api/admin/search"
method: GET
path: "/api/admin/search"
tags: ["Admin: Search"]
---

# GET /api/admin/search

`GET /api/admin/search`

## Request

- The document declares no server URL.
- Auth: API key in cookie `session`

Search every course, lesson and blog post by what they say, in the request
locale, whatever state they are in: draft, archived and unlisted landing
pages, courses not completed yet, lessons of the newest build and
unpublished posts, each with its state. Open to any staff member (and over
MCP to one holding mcp.read), who may read the content; the locale must be
one their Staff Role allows. The public `searchCatalogue` keeps its filters.

## Query parameters

- `q` string, required
- `type` 'course' | 'lesson' | 'post': The kinds of record the catalogue search finds.
- `page` integer
- `perPage` integer

## Response `200`

The request has succeeded.

- AdminSearchResultPage: A page of results. Generic envelope reused by every admin list so the CRUD engine (TanStack Table) can read pagination uniformly.
  - `items` AdminSearchResult[], required
    - `type` 'course' | 'lesson' | 'post', required: The kinds of record the catalogue search finds.
    - `id` string, required: The typed id `adminFetch` takes: `course:LANDING_SLUG`, `lesson:COURSE_SLUG/LESSON_SLUG` or `post:SLUG`.
    - `title` string, required
    - `snippet` string, required: A few words of the record's text around the match, plain text.
    - `path` string, required: The record's page on the website once it is public: the locale prefix and the path, with no origin.
    - `state` string, required: Publication state of the landing page, lesson or post (`draft`, `published`, `archived`, ...).
    - `readiness` string, required: Readiness of the course (`draft`, `in_development`, `completed`); empty for a post.
  - `total` integer, required: Total rows across all pages (before pagination).
  - `page` integer, required: 1-based page number this response represents.
  - `perPage` integer, required: Page size used for this response.

## Other responses

- `default`: Default error response shared by every operation. `@error` emits an OpenAPI `default` response, keeping central transport failures typed without enumerating every status on every operation.

## Changes

- **2026-10-18** `9380d4c85a04`: 3 info
  - removed the non-success response with the status `401`
  - removed the non-success response with the status `403`
  - added the optional property `errors` to the response with the `default` status
- **2026-10-18** `23cc12c79080`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/hexlet-basics/apis/hexlet-basics-api/changes/api/admin/search/get.md)

---

[API](https://skmtc.dev/hexlet-basics/apis/hexlet-basics-api.md) · [All operations](https://skmtc.dev/hexlet-basics/apis/hexlet-basics-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hexlet-basics/apis/hexlet-basics-api/revisions/51c7f596b47c?raw)
