Skip to content

feat(api): consistent POST /search endpoints for engrams, episodes, and entities#1

Merged
vthunder merged 2 commits intomainfrom
api/search-post
Feb 23, 2026
Merged

feat(api): consistent POST /search endpoints for engrams, episodes, and entities#1
vthunder merged 2 commits intomainfrom
api/search-post

Conversation

@vthunder
Copy link
Owner

@vthunder vthunder commented Feb 22, 2026

Summary

Moves all resource search from `GET /{resource}?query=` to `POST /{resource}/search` with a JSON body, making the pattern consistent across all three resource types.

New endpoints

  • `POST /v1/engrams/search` — semantic search via spreading activation
  • `POST /v1/episodes/search` — text search over episode content
  • `POST /v1/entities/search` — text search over entity names and aliases

Changed endpoints

  • `GET /v1/engrams` — list only (no `?query=`)
  • `GET /v1/episodes` — list only, all filters still compose freely (`?channel=`, `?unconsolidated=`, `?before=`, `?level=`)
  • `GET /v1/entities` — list only (no `?query=`)

Request body (all three search endpoints)

```json
{"query": "...", "limit": 10, "detail": "full", "level": 0}
```

Motivation

GET request bodies are undefined behavior in HTTP. A query string for semantic search can grow arbitrarily large (future: pre-computed embeddings in the body), so POST is the correct method.

Keeping a consistent pattern across all three resource types — GET = list, POST /search = search — makes the API easier to reason about and extend.

Updated docs

  • `docs/api.md`
  • `openapi.yaml`
  • `README.md`
  • `CHANGELOG.md`

Test plan

  • `go test ./internal/api/... -tags fts5` passes
  • `POST /v1/engrams/search` with valid body returns 200
  • `POST /v1/episodes/search` with valid body returns 200
  • `POST /v1/entities/search` with valid body returns 200
  • All three search endpoints return 400 for missing `query`
  • `GET /v1/engrams`, `GET /v1/episodes`, `GET /v1/entities` still list without search
  • bud2 PR merged alongside this one (uses updated client)

🤖 Generated with Claude Code

GET requests with large query bodies are technically undefined behavior
in HTTP. Move semantic search to POST /v1/engrams/search with a JSON
body containing query, limit, detail, and level fields.

GET /v1/engrams remains for listing all engrams (with optional threshold
filter). The query path is removed from that handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extend the search-as-POST pattern from engrams to all three resource
types. GET list endpoints are now list-only; search always uses POST
with a JSON body containing query, limit, detail, and level.

- POST /v1/episodes/search — text search over episode content
- POST /v1/entities/search — text search over entity names and aliases
- Remove ?query= from GET /v1/episodes and GET /v1/entities
- Update openapi.yaml, docs/api.md, README.md, CHANGELOG.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vthunder vthunder changed the title feat(api): add POST /v1/engrams/search endpoint feat(api): consistent POST /search endpoints for engrams, episodes, and entities Feb 23, 2026
@vthunder vthunder merged commit 659b2ce into main Feb 23, 2026
1 check passed
@vthunder vthunder deleted the api/search-post branch February 23, 2026 10:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant