Search
One endpoint, one parameter. It searches the published posts of the project the credential belongs to, and nothing else.
Using it
| Método | Ruta | Qué hace | Autenticación |
|---|---|---|---|
| GET | /v1/blog/search | Search posts | Key or session |
bash
curl -G 'https://api.cmskite.com/v1/blog/search' \
-H "authorization: Bearer $KEY" \
--data-urlencode 'q=port congestion' \
--data-urlencode 'limit=20'Results come back in the same shape as a post listing, so the code that renders a listing renders a search result without changes. They are ranked by relevance, which is not a stable order to page through, so a search answers with one page and no cursor: ask for as many results as you want to show with limit.
What it does and does not do
- Searches titles, excerpts and bodies, with a match in the title counting most, then the excerpt.
- Matches whole words, not parts of words:
portfinds “port” but not “export” or “portal”. Case does not matter, English words match their basic plurals (portsfinds “port”), and common words such as “the” and “and” are ignored. Other languages, Hindi included, match words only as they are spelled. - Published content only with a project API key. A draft is not findable by searching for it with the key your site uses.
- Handles the punctuation people type. Quotes, apostrophes and stray brackets come back as results rather than as a parse error.
- Ranks by relevance.
- Scoped to one project, because the credential is.
Search is a paid capability. The free plan does not include it; the endpoint answers
403 ENTITLEMENT_REQUIRED naming blog.search.enabled. ?q= on the posts listing applies the same whole-word match on every plan, but keeps the listing in date order rather than ranking it — enough for a small site.In a site
A search route that does not leak your key
ts
// app/api/search/route.ts -- runs on your server, so the key stays there.
export async function GET(request: Request) {
const q = new URL(request.url).searchParams.get('q')?.trim()
if (!q) return Response.json({ data: [] })
const url = new URL('https://api.cmskite.com/v1/blog/search')
url.searchParams.set('q', q)
url.searchParams.set('limit', '20')
const res = await fetch(url, {
headers: { authorization: `Bearer ${process.env.CMSKITE_API_KEY}` },
// Search results change when content does, not on a timer you pick.
next: { revalidate: 300 },
})
if (!res.ok) return Response.json({ data: [] }, { status: 502 })
return Response.json(await res.json())
}






