Docs / Search API

Search a project

POST a question, get back ranked passages.

Endpoint

1POST /grape/{project}/search

Example

A real request, and the response Grape returned in 9 ms, trimmed to two passages.

.cURL
1curl -X POST https://grape-industries.vercel.app/grape/$PROJECT/search \2  -H "Authorization: Bearer $GRAPE_KEY" \3  -d '{"query": "How many hearts does an octopus have?", "limit": 2}'
.JSON
1{2  "total": 173,3  "coverage": 0.84,4  "terms": ["many", "heart", "octopu"],5  "hits": [6    { "path": "Octopus.txt", "line": 32, "score": 26.1,7      "text": "... They have three hearts; a systemic or main heart ..." },8    { "path": "Octopus.txt", "line": 33, "score": 18.4,9      "text": "The systemic heart has muscular contractile walls ..." }10  ]11}

Request fields

FieldTypeDescription
querystringThe question in plain words. Grape chooses the search terms. Required, or queries.
queriesarrayInstead of query: one question per part. Each part is ranked on its own, then merged.
limitnumberHow many passages to return. Defaults to 6.
snippetnumberCut each passage to about this many characters, centred on the match.
rerankbooleanSet to false to skip the reranker and the off-topic check. On by default.

Response fields

FieldTypeDescription
hitsarrayRanked passages: path, line (and page for PDFs), score, text, and section: the heading or code definition the line sits under.
coveragenumber0 to 1: how much of the question the best passage explains.
termsarrayThe words Grape actually searched for.
totalnumberHow many lines matched before ranking.
refusedbooleanPresent and true when the question is clearly not covered by the documents. hits is empty.
filesarrayPresent when coverage is under 0.5: up to 5 files whose name, opening line or terms share the question's words. Search again with their terms.
rerank_scorenumberOn each hit, for English questions: the reranker's score. Higher is closer.

English questions over English passages are reranked by a small cross-encoder that runs on our server, and a clearly off-topic question comes back with refused: true. Your app can answer "Not in the documents" without calling an LLM at all.