---
title: "Public Search"
method: POST
path: "/api/v1/public/{context_id}/search"
tags: ["public-search"]
---

# Public Search

`POST /api/v1/public/{context_id}/search`

## Request

- Base URL: `https://memory.kagura-ai.com` (the document declares no server; this is the origin it was published from)
- URL: `https://memory.kagura-ai.com/api/v1/public/{context_id}/search`
- Auth: none declared

Search public context with schema-aware response formatting.

Issue #238: Public REST API for external systems (EC inventory, docs, etc.).
Issue #626: Optional API-key attribution via ``Authorization: Bearer
<kagura_…>``. A bound key gets a per-key rate-limit bucket and audit
attribution; an unbound key (owner / workspace-scoped) is rejected so
callers don't accidentally route their primary credentials through a
public path. Anonymous access continues to work without any header.

Authentication:
    - Workspace member session (authenticated access, no rate limit)
    - Public-bound API key (#626) — per-key rate limit, audit-attributed
    - Anonymous access (rate limited to 50 req/min per context, shared)

Rate Limits:
    - Anonymous access: 50 requests/minute per context (shared bucket)
    - Public-bound key: per-key bucket from workspace plan tier
      (``bound_public_calls_per_minute``)
    - Workspace members: No limit (uses normal workspace quota)

Request:
    POST /api/v1/public/{context_id}/search
    Headers:
        Authorization: Bearer kagura_…    (optional; required only for
                                           attributed/bound-key access)
    Body:
    {
        "query": "商品名 価格",
        "limit": 10,
        "use_rerank": false
    }

Response:
    {
        "status": "success",
        "query": "商品名 価格",
        "results": [
            {
                "memory_id": "...",
                "content": "商品名: ..., 価格: ...",
                "score": 0.95,
                "metadata": {...},
                "highlighted": {...}
            }
        ],
        "count": 5,
        "context_id": "...",
        "resource_id": "ec_products",
        "schema_version": 1
    }

Errors:
    - 401: API key supplied but invalid / expired
    - 403: Context is not public, OR API key is not public-bound, OR
           API key is bound to a different context (CWE-639 IDOR)
    - 404: Context not found
    - 429: Rate limit exceeded (anonymous or per-key bucket), or the
           workspace's plan has no public API allowance (#1939)

## Path parameters

- `context_id` string, uuid, required

## Headers

- `authorization` string, nullable

## Request body

- PublicSearchRequest: Public search request.
  - `query` string, required: Search query
  - `limit` integer: Maximum results (default: 10, max: 100)
  - `use_rerank` boolean: Enable reranking for better results
  - `search_mode` string: Search mode: hybrid (default), semantic, keyword

## Response `200`

Successful Response

- PublicSearchResponse: Public search response.
  - `status` string
  - `query` string, required
  - `results` PublicSearchResult[], required
    - `memory_id` string, required
    - `content` string, required
    - `score` number, required
    - `metadata` object, required
    - `highlighted` object, nullable
  - `count` integer, required
  - `context_id` string, required
  - `resource_id` string, nullable
  - `schema_version` integer, nullable
  - `degraded` boolean, nullable
  - `degraded_reason` string, nullable

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/kagura-ai/apis/kagura-memory-cloud.md) · [All operations](https://skmtc.dev/kagura-ai/apis/kagura-memory-cloud/llms.txt) · [OpenAPI document](https://skmtc.dev/kagura-ai/apis/kagura-memory-cloud/revisions/09f17f5ada29?raw)
