diff --git a/README.md b/README.md index 76ec10f..a527825 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,11 @@ **5-14x cheaper than Perplexity. Native x402 payments. Zero friction for agents.** +## Docs +- [OpenAPI](openapi.json) +- [Agent Guide](docs/AGENT_GUIDE.md) +- [Pricing](docs/PRICING.md) + ## Endpoints | Endpoint | Price | Description | diff --git a/docs/AGENT_GUIDE.md b/docs/AGENT_GUIDE.md new file mode 100644 index 0000000..f671efc --- /dev/null +++ b/docs/AGENT_GUIDE.md @@ -0,0 +1,83 @@ +# Queryx — Agent Guide + +This document is written for **AI agents** consuming Queryx programmatically. + +## What Queryx is + +Queryx is a paid HTTP API that returns: +- `answer` — synthesized short answer +- `sources[]` — citations (title/url/snippet/published) +- `confidence` — 0..1 +- `freshness` — timestamps + result age + +## Payment model (x402) + +Queryx uses **x402**: pay-per-request micropayments in **USDC on Base**. + +- If you call a paid endpoint without payment, you should receive `HTTP 402`. +- The 402 response should include instructions for how to pay (facilitator / required headers). +- After paying, **retry the same request** with the required payment headers. + +Reference: +- x402 overview: https://x402.org + +### How to handle x402 in agent code (recommended loop) + +1. Make request normally. +2. If `200`: parse JSON. +3. If `402`: parse payment instructions, obtain a valid payment proof/receipt. +4. Retry with payment header(s). + +Pseudo: + +```ts +async function x402Fetch(url, init) { + const r1 = await fetch(url, init); + if (r1.status !== 402) return r1; + + const payment = await buildPaymentFrom402(r1); // facilitator-specific + const headers = new Headers(init.headers || {}); + headers.set('X-Payment', payment); + + return fetch(url, { ...init, headers }); +} +``` + +## Endpoints + +### `GET /v1/search` +- Purpose: web search + synthesis +- Typical price: **0.001 USDC** +- Query params: + - `q` (required) + - `count` (optional) + +### `GET /v1/search/news` +- Purpose: news search + synthesis +- Typical price: **0.001 USDC** +- Query params: + - `q` (required) + - `count` (optional) + - `freshness` (optional: day|week|month) + +### `POST /v1/search/deep` +- Purpose: deeper multi-source research +- Typical price: **0.005 USDC** +- JSON body: + - `query` (required) + - `depth` (optional) + - `maxSources` (optional) + +### `GET /health` +- Free + +## Best practices + +- Cache responses when appropriate. +- Deduplicate repeated queries. +- Prefer small `count` unless you truly need more citations. +- If you receive `429`, backoff with jitter. + +## Schemas + +Canonical contract lives in `openapi.json` (OpenAPI 3.1). diff --git a/docs/PRICING.md b/docs/PRICING.md new file mode 100644 index 0000000..48798db --- /dev/null +++ b/docs/PRICING.md @@ -0,0 +1,42 @@ +# Queryx — Pricing + +Queryx endpoints are priced in **USDC on Base** and collected via **x402**. + +Reference: https://x402.org + +## Per-endpoint pricing + +- `GET /v1/search`: **$0.001 USDC** per call +- `GET /v1/search/news`: **$0.001 USDC** per call +- `POST /v1/search/deep`: **$0.005 USDC** per call +- `GET /health`: free + +## Base units + +USDC has 6 decimals. + +- $0.001 USDC = **1000** (micro-USDC) +- $0.005 USDC = **5000** (micro-USDC) + +## Cost comparison (rough, for positioning) + +This table is intentionally high-level; prices vary by plan and time. + +- Queryx: predictable, per-call USDC micropayments (x402) +- Perplexity/Tavily/Brave: subscription or API-key based; often higher fixed costs + +## Example monthly spend + +Assuming average mix of endpoints: + +- 1k calls of `/v1/search` → **$1.00** +- 10k calls of `/v1/search` → **$10.00** +- 100k calls of `/v1/search` → **$100.00** + +Deep research: + +- 1k calls of `/v1/search/deep` → **$5.00** + +## Facilitator address + +Payment facilitator address is implementation/config dependent. If you need the address, call a paid endpoint and parse the `402` instructions. diff --git a/openapi.json b/openapi.json new file mode 100644 index 0000000..edea3ea --- /dev/null +++ b/openapi.json @@ -0,0 +1,304 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Queryx", + "version": "1.0.0", + "description": "Agent-native web search API. Pay per request in USDC via x402 on Base.\n\nNote: This OpenAPI spec documents the intended public contract. Payment details depend on the x402 facilitator implementation." + }, + "servers": [ + { + "url": "https://queryx.run", + "description": "Production" + } + ], + "security": [ + { + "x402": [] + } + ], + "tags": [ + { "name": "search", "description": "Paid search endpoints" }, + { "name": "health", "description": "Health" } + ], + "paths": { + "/health": { + "get": { + "tags": ["health"], + "summary": "Health check", + "security": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/Health" }, + "examples": { + "ok": { "value": { "status": "ok" } } + } + } + } + } + } + } + }, + "/v1/search": { + "get": { + "tags": ["search"], + "summary": "Web search + AI synthesis", + "description": "Paid endpoint (x402). Typical price: 0.001 USDC per call.", + "parameters": [ + { "$ref": "#/components/parameters/q" }, + { "$ref": "#/components/parameters/count" } + ], + "responses": { + "200": { + "description": "Search response", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/SearchResponse" }, + "examples": { + "example": { + "value": { + "query": "what is x402", + "answer": "x402 is a payment scheme for HTTP APIs where clients pay per request (HTTP 402) ...", + "sources": [ + { + "title": "x402", + "url": "https://x402.org", + "snippet": "...", + "published": "2026-02-01T00:00:00Z" + } + ], + "confidence": 0.72, + "freshness": { "fetchedAt": "2026-02-28T12:00:00Z", "resultsAge": "4h" }, + "model": "queryx-fast-v1", + "tokens": { "in": 320, "out": 180 } + } + } + } + } + } + }, + "402": { "$ref": "#/components/responses/PaymentRequired" }, + "422": { "$ref": "#/components/responses/UnprocessableEntity" }, + "429": { "$ref": "#/components/responses/RateLimited" }, + "500": { "$ref": "#/components/responses/ServerError" } + } + } + }, + "/v1/search/news": { + "get": { + "tags": ["search"], + "summary": "News-focused search + synthesis", + "description": "Paid endpoint (x402). Typical price: 0.001 USDC per call.", + "parameters": [ + { "$ref": "#/components/parameters/q" }, + { "$ref": "#/components/parameters/count" }, + { + "name": "freshness", + "in": "query", + "required": false, + "schema": { "type": "string", "enum": ["day", "week", "month"] }, + "description": "Optional freshness window for news search." + } + ], + "responses": { + "200": { + "description": "Search response", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/SearchResponse" } } + } + }, + "402": { "$ref": "#/components/responses/PaymentRequired" }, + "422": { "$ref": "#/components/responses/UnprocessableEntity" }, + "429": { "$ref": "#/components/responses/RateLimited" }, + "500": { "$ref": "#/components/responses/ServerError" } + } + } + }, + "/v1/search/deep": { + "post": { + "tags": ["search"], + "summary": "Deep research (multi-source)", + "description": "Paid endpoint (x402). Typical price: 0.005 USDC per call.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/DeepSearchRequest" }, + "examples": { + "example": { + "value": { + "query": "compare Brave Search vs Tavily for agents", + "depth": 2, + "maxSources": 12 + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Search response", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/SearchResponse" } } + } + }, + "402": { "$ref": "#/components/responses/PaymentRequired" }, + "422": { "$ref": "#/components/responses/UnprocessableEntity" }, + "429": { "$ref": "#/components/responses/RateLimited" }, + "500": { "$ref": "#/components/responses/ServerError" } + } + } + } + }, + "components": { + "securitySchemes": { + "x402": { + "type": "apiKey", + "in": "header", + "name": "X-Payment", + "description": "x402 payment proof / receipt header (implementation-specific). Clients should be prepared to receive HTTP 402 with facilitator instructions and then retry with payment header(s). See https://x402.org" + } + }, + "parameters": { + "q": { + "name": "q", + "in": "query", + "required": true, + "schema": { "type": "string", "minLength": 1 }, + "description": "Search query" + }, + "count": { + "name": "count", + "in": "query", + "required": false, + "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 10 }, + "description": "Number of sources to retrieve" + } + }, + "responses": { + "PaymentRequired": { + "description": "Payment required (x402)", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/Error" }, + "examples": { + "payment_required": { + "value": { + "error": "payment_required", + "message": "Payment required. Follow facilitator instructions and retry with payment headers.", + "code": "X402_PAYMENT_REQUIRED" + } + } + } + } + } + }, + "UnprocessableEntity": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/Error" }, + "examples": { "invalid": { "value": { "error": "invalid_request", "message": "Invalid request", "code": "VALIDATION_ERROR" } } } + } + } + }, + "RateLimited": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/Error" }, + "examples": { "rate_limited": { "value": { "error": "rate_limited", "message": "Too many requests", "code": "RATE_LIMIT" } } } + } + } + }, + "ServerError": { + "description": "Server error", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/Error" }, + "examples": { "server_error": { "value": { "error": "server_error", "message": "Unexpected error", "code": "INTERNAL" } } } + } + } + } + }, + "schemas": { + "Health": { + "type": "object", + "additionalProperties": false, + "properties": { + "status": { "type": "string", "enum": ["ok"] } + }, + "required": ["status"] + }, + "DeepSearchRequest": { + "type": "object", + "additionalProperties": false, + "properties": { + "query": { "type": "string", "minLength": 1 }, + "depth": { "type": "integer", "minimum": 1, "maximum": 5, "default": 2 }, + "maxSources": { "type": "integer", "minimum": 1, "maximum": 50, "default": 12 } + }, + "required": ["query"] + }, + "Source": { + "type": "object", + "additionalProperties": false, + "properties": { + "title": { "type": "string" }, + "url": { "type": "string", "format": "uri" }, + "snippet": { "type": "string" }, + "published": { "type": "string", "format": "date-time" } + }, + "required": ["title", "url", "snippet"] + }, + "Freshness": { + "type": "object", + "additionalProperties": false, + "properties": { + "fetchedAt": { "type": "string", "format": "date-time" }, + "resultsAge": { "type": "string", "description": "Human-readable age, e.g. '4h'" } + }, + "required": ["fetchedAt", "resultsAge"] + }, + "Tokens": { + "type": "object", + "additionalProperties": false, + "properties": { + "in": { "type": "integer", "minimum": 0 }, + "out": { "type": "integer", "minimum": 0 } + }, + "required": ["in", "out"] + }, + "SearchResponse": { + "type": "object", + "additionalProperties": false, + "properties": { + "query": { "type": "string" }, + "answer": { "type": "string" }, + "sources": { + "type": "array", + "items": { "$ref": "#/components/schemas/Source" } + }, + "confidence": { "type": "number", "minimum": 0, "maximum": 1 }, + "freshness": { "$ref": "#/components/schemas/Freshness" }, + "model": { "type": "string" }, + "tokens": { "$ref": "#/components/schemas/Tokens" } + }, + "required": ["query", "answer", "sources", "confidence", "freshness", "model", "tokens"] + }, + "Error": { + "type": "object", + "additionalProperties": false, + "properties": { + "error": { "type": "string" }, + "message": { "type": "string" }, + "code": { "type": "string" } + }, + "required": ["error", "message", "code"] + } + } + } +}