{ "openapi": "3.1.0", "info": { "title": "TradeDataHub Public API", "version": "1.0.0", "description": "Free machine-readable discovery endpoints over the canonical product catalog. An agent can go from zero knowledge to a specific product, its price, a masked preview, and the paid retrieval resource without scraping HTML. x402 agent payment access is available for TESTNET integration and testing only. Network: Base Sepolia (eip155:84532). Mainnet settlement is NOT enabled. Human Stripe purchasing remains a separate, unchanged path. Agents may inspect the HTTP 402 Payment-Required challenge without making any payment. See https://www.tradedatahub.net/developers/." }, "servers": [ { "url": "https://www.tradedatahub.net" } ], "tags": [ { "name": "discovery", "description": "Zero-knowledge inventory discovery (coverage, states, trades, cities)." }, { "name": "datasets", "description": "Dataset metadata, pricing, masked previews." }, { "name": "commerce", "description": "x402 TESTNET paid retrieval. Mainnet is NOT enabled." } ], "paths": { "/api/v1/": { "get": { "tags": [ "discovery" ], "summary": "API index \u2014 endpoint list and paid access pointer", "description": "Returns the free discovery endpoint list and the x402 TESTNET paid endpoint pointer.", "responses": { "200": { "description": "Endpoint index", "content": { "application/json": { "schema": { "type": "object", "required": [ "api_version", "endpoints" ], "properties": { "api_version": { "type": "string" }, "endpoints": { "type": "array", "items": { "type": "string" } }, "paid_endpoint": { "type": "string", "description": "x402 TESTNET ONLY (Base Sepolia eip155:84532); unpaid requests receive HTTP 402 Payment Required with the challenge; mainnet settlement is NOT enabled." } } } } } } } } }, "/api/v1/texas-trades-teaser.json": { "get": { "tags": [ "discovery" ], "summary": "Get a browser-safe masked trade-business teaser", "responses": { "200": { "description": "Masked teaser without paid contact records", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Preview" } } } } } } }, "/api/v1/coverage": { "get": { "tags": [ "discovery" ], "summary": "Overall platform coverage and pricing model (start here)", "responses": { "200": { "description": "Coverage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Coverage" }, "example": { "api_version": "1.0.0", "record_count": 33753, "live_states": 7, "trades": 50, "cities": 170, "product_count": 8588, "currency": "usd", "price_model": "one-time CSV per dataset", "last_updated": "2026-08-19" } } } } } } }, "/api/v1/states": { "get": { "tags": [ "discovery" ], "summary": "List live states with record counts and prices", "responses": { "200": { "description": "States", "content": { "application/json": { "schema": { "type": "object", "required": [ "api_version", "states" ], "properties": { "api_version": { "type": "string" }, "states": { "type": "array", "items": { "$ref": "#/components/schemas/State" } } } } } } } } } }, "/api/v1/trades": { "get": { "tags": [ "discovery" ], "summary": "List trades with aggregate record counts", "responses": { "200": { "description": "Trades", "content": { "application/json": { "schema": { "type": "object", "required": [ "api_version", "trades" ], "properties": { "api_version": { "type": "string" }, "trades": { "type": "array", "items": { "$ref": "#/components/schemas/Trade" } } } } } } } } } }, "/api/v1/cities": { "get": { "tags": [ "discovery" ], "summary": "List cities (filter by ?state=)", "parameters": [ { "name": "state", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Exact state name as returned by /api/v1/states, e.g. `Texas` (case-sensitive)." } ], "responses": { "200": { "description": "Cities (paginated)", "content": { "application/json": { "schema": { "type": "object", "required": [ "api_version", "pagination", "cities" ], "properties": { "api_version": { "type": "string" }, "pagination": { "$ref": "#/components/schemas/Pagination" }, "cities": { "type": "array", "items": { "$ref": "#/components/schemas/City" } } } } } } }, "404": { "description": "Unknown state", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/api/v1/datasets": { "get": { "tags": [ "datasets" ], "summary": "List datasets with optional filters (deterministic full catalog enumeration)", "description": "Use filters to enumerate the complete purchasable catalog without scraping HTML. Filter values must match canonical names exactly (e.g. `state=Texas`, `trade=HVAC Contractor`). Paginate with limit/offset (limit<=100).", "parameters": [ { "name": "state", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Exact state name, e.g. `Texas`." }, { "name": "trade", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Exact trade name, e.g. `Roofer`." }, { "name": "city", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Exact city name." }, { "name": "type", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "city_trade", "state_trade", "state", "mega_pack" ] } }, { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 100 } }, { "name": "offset", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 0, "default": 0 } } ], "responses": { "200": { "description": "Dataset listings (paginated)", "content": { "application/json": { "schema": { "type": "object", "required": [ "api_version", "pagination", "datasets" ], "properties": { "api_version": { "type": "string" }, "pagination": { "$ref": "#/components/schemas/Pagination" }, "datasets": { "type": "array", "items": { "$ref": "#/components/schemas/Dataset" } } } } } } }, "400": { "description": "Invalid limit/offset", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/api/v1/datasets/{product_id}": { "get": { "tags": [ "datasets" ], "summary": "Get a single dataset's public metadata", "parameters": [ { "$ref": "#/components/parameters/ProductId" } ], "responses": { "200": { "description": "Dataset metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Dataset" } } } }, "404": { "description": "Dataset not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/api/v1/datasets/{product_id}/price": { "get": { "tags": [ "datasets" ], "summary": "Get price and availability", "parameters": [ { "$ref": "#/components/parameters/ProductId" } ], "responses": { "200": { "description": "Price metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Price" }, "example": { "api_version": "1.0.0", "product_id": "state-trade:florida:appliance-repair-technician", "product_type": "state_trade", "state": "Florida", "trade": "Appliance Repair Technician", "record_count": 434, "amount_cents": 1900, "price": "19.00", "currency": "USD", "available_for_purchase": true } } } }, "404": { "description": "Dataset not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/api/v1/datasets/{product_id}/preview": { "get": { "tags": [ "datasets" ], "summary": "Get a masked availability preview (no paid contact values)", "description": "Returns masked preview records only: business identities are replaced with `Masked business` and only availability booleans (phone_available/website_available) plus city, trade, and verification_date are exposed. Actual contact values are delivered only after purchase.", "parameters": [ { "$ref": "#/components/parameters/ProductId" } ], "responses": { "200": { "description": "Masked preview", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Preview" } } } }, "404": { "description": "Preview unavailable for this dataset type or product", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/api/v1/datasets/{product_id}/download": { "get": { "tags": [ "commerce" ], "summary": "Paid dataset retrieval via x402 (TESTNET ONLY)", "description": "x402 paid retrieval. TESTNET ONLY: network is Base Sepolia (eip155:84532); mainnet settlement is NOT enabled. With no PAYMENT-SIGNATURE header the endpoint returns HTTP 402 Payment Required including the current x402 Payment-Required challenge (the server generates it dynamically; do not hardcode it). After a valid TESTNET settlement the endpoint returns 200 with a one-shot authorized download URL. Human Stripe purchasing is a separate, unchanged path. Agents may inspect the 402 challenge without making any payment.", "parameters": [ { "$ref": "#/components/parameters/ProductId" } ], "responses": { "200": { "description": "Authorized delivery after valid TESTNET settlement (one-shot download URL)", "content": { "application/json": { "schema": { "type": "object", "required": [ "api_version", "product_id", "download_url" ], "properties": { "api_version": { "type": "string" }, "product_id": { "type": "string" }, "filename": { "type": "string" }, "download_url": { "type": "string" }, "record_count": { "type": "integer" } } } } } }, "402": { "description": "Payment Required \u2014 includes the current x402 Payment-Required challenge", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentRequired" } } } }, "400": { "description": "Invalid payment payload/signature (fail-closed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Dataset not found, or the testnet rail is disabled (fail-closed `not_yet_available`)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Payment replay / duplicate settlement rejected (fail-closed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } } }, "components": { "parameters": { "ProductId": { "name": "product_id", "in": "path", "required": true, "schema": { "type": "string", "maxLength": 128 }, "description": "Canonical product identifier. Formats: `state:{state_slug}` (e.g. `state:texas`), `state-trade:{state_slug}:{trade_slug}` (e.g. `state-trade:florida:roofer`), `city-trade:{state_slug}:{city_slug}:{trade_slug}` (e.g. `city-trade:texas:austin:plumber`), `mega-pack:seven-live-states`. Slugs are lowercase hyphenated; always derive product_id values from the discovery endpoints rather than constructing them ad hoc." } }, "schemas": { "Pagination": { "type": "object", "required": [ "total", "limit", "offset" ], "properties": { "total": { "type": "integer" }, "limit": { "type": "integer" }, "offset": { "type": "integer" } } }, "Coverage": { "type": "object", "required": [ "api_version", "record_count", "currency", "price_model" ], "properties": { "api_version": { "type": "string" }, "record_count": { "type": "integer" }, "live_states": { "type": "integer" }, "trades": { "type": "integer" }, "cities": { "type": "integer" }, "product_count": { "type": "integer" }, "currency": { "type": "string" }, "price_model": { "type": "string" }, "last_updated": { "type": "string", "nullable": true } } }, "State": { "type": "object", "required": [ "product_id", "state", "record_count", "price", "currency" ], "properties": { "product_id": { "type": "string" }, "state": { "type": "string" }, "record_count": { "type": "integer" }, "amount_cents": { "type": "integer" }, "price": { "type": "string" }, "currency": { "type": "string" }, "last_updated": { "type": "string" }, "available_for_purchase": { "type": "boolean" } } }, "Trade": { "type": "object", "required": [ "trade", "record_count", "product_count" ], "properties": { "trade": { "type": "string" }, "record_count": { "type": "integer" }, "product_count": { "type": "integer" } } }, "City": { "type": "object", "required": [ "state", "city", "record_count", "trade_count" ], "properties": { "state": { "type": "string" }, "city": { "type": "string" }, "record_count": { "type": "integer" }, "trade_count": { "type": "integer" } } }, "Dataset": { "type": "object", "required": [ "product_id", "product_type", "record_count", "price", "currency" ], "properties": { "product_id": { "type": "string" }, "product_type": { "type": "string", "enum": [ "city_trade", "state_trade", "state", "mega_pack" ] }, "state": { "type": "string" }, "city": { "type": "string" }, "trade": { "type": "string" }, "record_count": { "type": "integer" }, "amount_cents": { "type": "integer" }, "price": { "type": "string" }, "currency": { "type": "string" }, "last_updated": { "type": "string" }, "available_for_purchase": { "type": "boolean" } } }, "Price": { "$ref": "#/components/schemas/Dataset" }, "PreviewRecord": { "type": "object", "required": [ "business", "city", "trade", "phone_available", "website_available" ], "properties": { "business": { "type": "string", "description": "Always the literal `Masked business` in previews.", "example": "Masked business" }, "city": { "type": "string" }, "trade": { "type": "string" }, "phone_available": { "type": "boolean", "description": "Whether the purchased record includes a phone value." }, "website_available": { "type": "boolean", "description": "Whether the purchased record includes a website value." }, "verification_date": { "type": "string", "description": "Source-pipeline verification date (YYYY-MM-DD)." } } }, "Preview": { "type": "object", "required": [ "api_version", "product_id", "classification", "records" ], "properties": { "api_version": { "type": "string" }, "product_id": { "type": "string" }, "classification": { "type": "string" }, "record_count": { "type": "integer" }, "fields": { "type": "array", "items": { "type": "string" } }, "records": { "type": "array", "items": { "$ref": "#/components/schemas/PreviewRecord" } }, "notice": { "type": "string" } } }, "Error": { "type": "object", "required": [ "api_version", "error" ], "properties": { "api_version": { "type": "string" }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "details": { "type": "object", "additionalProperties": true } } } } }, "PaymentRequired": { "type": "object", "required": [ "api_version", "error", "payment_required" ], "description": "HTTP 402 body. The live challenge is generated dynamically by the server; treat the `payment_required` object as authoritative and never hardcode it. TESTNET ONLY (Base Sepolia eip155:84532).", "properties": { "api_version": { "type": "string" }, "error": { "type": "object", "properties": { "code": { "type": "string", "example": "payment_required" }, "message": { "type": "string" } } }, "payment_required": { "type": "object", "properties": { "x402Version": { "type": "integer" }, "resource": { "type": "object", "properties": { "url": { "type": "string" }, "mimeType": { "type": "string" } } }, "accepts": { "type": "array", "items": { "type": "object", "required": [ "network", "asset", "amount", "payTo" ], "properties": { "network": { "type": "string", "description": "CAIP-2 chain id; testnet is `eip155:84532` (Base Sepolia)." }, "asset": { "type": "string", "description": "USDC contract address on the testnet network." }, "amount": { "type": "string", "description": "Atomic units (6 decimals)." }, "payTo": { "type": "string", "description": "Testnet recipient address." } } } } } } } } } } }