quarryDocs

Ask over HTTP

Ask one dataset a question over plain HTTP, paying per question with x402 or with a subscription, and read the passages it returns.

Two HTTP routes answer questions. Over MCP, use ask instead: see the MCP server, whose answer adds citations to each passage.

RouteWho can askCost
POST /{username}/{slug}AnyoneFree datasets: nothing. Others: the price per question, paid with x402
POST /api/agent/queryA quarry account, with an API key or an OAuth tokenOne question from the account's subscription. Free datasets aren't answered here: use the dataset route

Pay per question

curl https://quarry.market/alice/market-outlook \
  -H "Content-Type: application/json" \
  -d '{ "query": "Which segment grew fastest?", "top_k": 5 }'
FieldTypeLimits
querystring, required1 to 2,000 characters
top_kinteger, optionalPassages to return, 1 to 20, default 5

A free dataset answers right away. A paid one answers 402 with the payment requirements: sign and send again as described in Paying with x402. The route never uses a subscription.

An agent signed in to a quarry account gets from ask the body to send here, in quarry.web_payment.body, for a wallet that pays web requests but can't pay inside an MCP call. Send it as is: its account_token lists the purchase on that account, and the answer adds purchase_url, the purchase's page there. A token works for its one question for 24 hours. An expired one, or one made for another question, gets 400 with INVALID_ACCOUNT_TOKEN before anything is paid.

With a subscription

curl https://quarry.market/api/agent/query \
  -H "Authorization: Bearer $QUARRY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "alice",
    "slug": "market-outlook",
    "query": "Which segment grew fastest?",
    "top_k": 5,
    "request_id": "outlook-2026-09-26-001"
  }'

QUARRY_API_KEY is an API key; an OAuth token from a connected agent works too. A regular quarry login token is refused.

FieldTypeLimits
usernamestring, requiredThe seller's handle, 1 to 60 characters
slugstring, requiredThe dataset, 1 to 80 characters
querystring, required1 to 2,000 characters
top_kinteger, optional1 to 20, default 5
request_idstring, required1 to 128 characters: letters, digits, _, ., :, or -

An Idempotency-Key header can carry the request ID instead, and wins over the body. Use a new ID for each new question, and the same one to retry: the rules are in the Subscription API.

Response

Both routes return:

{
  "dataset": { "slug": "market-outlook", "name": "Market outlook" },
  "query": "Which segment grew fastest?",
  "results": [
    {
      "chunk_id": "a84b2e07-034c-4b1f-97b5-90e34cb62f51",
      "content": "Self-serve revenue grew 41% year over year, the fastest of any segment.",
      "relevance": 0.83,
      "score": 0.0325,
      "vector_score": 0.71,
      "text_score": 0.12,
      "rerank_score": 0.83,
      "filename": "q3-outlook.pdf",
      "chunk_index": 42,
      "heading": "Segments",
      "heading_path": ["Results", "Segments"],
      "page_start": 12,
      "page_end": 12,
      "row_start": null,
      "row_end": null,
      "document_updated_at": "2026-09-20T10:00:00Z"
    }
  ]
}

Result fields

FieldMeaning
chunk_idThe passage's id
contentThe passage's text
relevanceHow well the passage answers the question, from 0 to 1; higher is better. The reranking model's score, or vector_score when reranking wasn't available. Compare it between the passages of one answer
scoreThe search's rank score, combining how well the passage ranks by meaning and by words. Small numbers (about 0.03 at most); higher is better
vector_scoreHow close the passage is to the question in meaning, from 0 to 1 (0 when only the word search found it)
text_scoreHow well the passage's words match the question's (0 when only the meaning search found it)
rerank_scoreThe reranking model's score, or null when reranking wasn't available
filenameThe source file
chunk_indexThe passage's position in its file
heading, heading_pathThe nearest heading, and the headings above it; null and empty when the file has none
page_start, page_endThe pages the passage comes from, or null
row_start, row_endThe rows of a CSV, TSV, JSON, or JSON Lines file the passage holds: spreadsheet rows (the header is row 1), JSON Lines lines, or JSON array elements counted from 1. null for other files
document_updated_atWhen the file last changed on quarry, not when the source was written

Results come best first: in the reranking model's order, or by score when reranking wasn't available. When the relevance check finds no passage that answers the question, both routes answer 404 with the error NO_MATCH and nothing is charged: no payment settles, and no subscription question is used. Passages that answer only part of the question still count.

The subscription route also returns quota (quota, used, reserved, remaining, resets_at, and ids, or null if the paid month ended meanwhile) and replayed, true when the answer is a saved one returned for a retry.

Errors use one format for both routes, except the x402 402 responses: see Error codes.

On this page

View as Markdown