HTTP API
The Weave REST API — 12 endpoints for collections, documents, retrieval, and search.
Weave exposes a Forge-native HTTP API under /v1. All endpoints expect and return JSON. Tenant isolation is enforced through middleware — the tenant and app are read from request headers or JWT claims depending on your Forge configuration.
Registering routes
import "github.com/xraph/weave/api"
weaveAPI := api.New(eng, router)
weaveAPI.RegisterRoutes(router)Or use the Forge extension, which registers routes automatically:
ext := extension.New(
extension.WithStore(pgStore),
extension.WithVectorStore(pgVec),
extension.WithEmbedder(emb),
)
forge.RegisterExtension(ext)Collection endpoints
POST /v1/collections
Create a new collection.
Request body:
{
"name": "product-docs",
"description": "Product documentation",
"embedding_model": "text-embedding-3-small",
"embedding_dims": 1536,
"chunk_strategy": "recursive",
"chunk_size": 512,
"chunk_overlap": 50,
"metadata": { "domain": "support" }
}Response: 201 Created — collection.Collection
GET /v1/collections
List collections for the current tenant.
Query params: limit, offset
Response: 200 OK — []*collection.Collection
GET /v1/collections/:collectionId
Get a collection by ID.
Response: 200 OK — collection.Collection
DELETE /v1/collections/:collectionId
Delete a collection and all its documents and chunks. Vectors are also removed from the vector store.
Response: 204 No Content
GET /v1/collections/:collectionId/stats
Get aggregate statistics for a collection.
Response: 200 OK
{
"collection_id": "col_01h455vb...",
"collection_name": "product-docs",
"document_count": 42,
"chunk_count": 1204,
"embedding_model": "text-embedding-3-small",
"chunk_strategy": "recursive"
}POST /v1/collections/:collectionId/reindex
Re-embed and re-store all chunks in the collection. Use after changing the embedding model.
Response: 204 No Content
Document endpoints
POST /v1/collections/:collectionId/documents
Ingest a single document — runs the full load → chunk → embed → store pipeline.
Request body:
{
"title": "Return Policy",
"content": "Our return policy allows...",
"source": "policy.md",
"source_type": "text/markdown",
"metadata": { "category": "support" }
}Response: 201 Created
{
"document_id": "doc_01h455vb...",
"chunk_count": 12,
"state": "ready"
}POST /v1/collections/:collectionId/documents/batch
Ingest multiple documents in a single request.
Request body:
{
"documents": [
{ "title": "Doc A", "content": "..." },
{ "title": "Doc B", "content": "..." }
]
}Response: 201 Created — []*engine.IngestResult
GET /v1/collections/:collectionId/documents
List documents in a collection.
Query params: state (pending | processing | ready | failed), limit, offset
Response: 200 OK — []*document.Document
GET /v1/documents/:documentId
Get a document by ID.
Response: 200 OK — document.Document
DELETE /v1/documents/:documentId
Delete a document and all its chunks from both metadata and vector stores.
Response: 204 No Content
Retrieval endpoints
POST /v1/collections/:collectionId/retrieve
Perform semantic retrieval within a collection.
Request body:
{
"query": "What is the return policy?",
"top_k": 5,
"min_score": 0.75,
"strategy": "similarity"
}Response: 200 OK
[
{
"chunk": {
"id": "chunk_01h455vb...",
"content": "Our return policy allows...",
"document_id": "doc_01h455vb...",
"collection_id": "col_01h455vb...",
"index": 0,
"token_count": 48
},
"score": 0.94
}
]POST /v1/search
Hybrid search across one or more collections.
Request body:
{
"query": "refund timeline",
"collections": ["col_01h455vb...", "col_02x..."],
"top_k": 10,
"min_score": 0.7,
"strategy": "mmr"
}Response: 200 OK — []engine.ScoredChunk (same schema as retrieve, merged and re-ranked)
Error responses
All endpoints return standard error JSON on failure:
{
"error": "collection not found",
"code": "NOT_FOUND"
}| HTTP status | Condition |
|---|---|
400 | Invalid input, missing required field |
404 | Collection or document not found for this tenant |
500 | Internal error (store, embedder, vector store) |