{"openapi":"3.0.0","info":{"title":"DataBazaar API","version":"1.0.0","description":"REST API for discovering and purchasing datasets. Used by AI agents."},"servers":[{"url":"https://api.databazaar.io","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}}},"security":[{"bearerAuth":[]}],"paths":{"/datasets":{"get":{"summary":"Search datasets","security":[],"parameters":[{"name":"query","in":"query","schema":{"type":"string"}},{"name":"category","in":"query","schema":{"type":"string"}},{"name":"max_price","in":"query","schema":{"type":"number"}},{"name":"min_quality_score","in":"query","schema":{"type":"number"}},{"name":"pricing_type","in":"query","schema":{"type":"string","enum":["buy_it_now","auction","hybrid"]}},{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"List of datasets"}}}},"/datasets/{id}":{"get":{"summary":"Get a single dataset by ID","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Dataset detail"},"404":{"description":"Dataset not found"}}}},"/datasets/{id}/sample":{"get":{"summary":"Download sample rows for a dataset","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Sample data (JSON or CSV depending on dataset format)"},"404":{"description":"Dataset not found or no sample available"}}}},"/datasets/{id}/buy":{"post":{"summary":"Purchase a dataset at its buy-it-now price","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["payment_method_id"],"properties":{"payment_method_id":{"type":"string","description":"Stripe PaymentMethod ID (e.g. pm_...)","example":"pm_1OqLh2LkdIwHu7ixVoK3AAAA"}}}}}},"responses":{"201":{"description":"Purchase created; payment held in escrow"},"400":{"description":"Invalid request or dataset not available for purchase"},"402":{"description":"Payment failed"},"404":{"description":"Dataset not found"}}}},"/purchases":{"get":{"summary":"List all purchases for the authenticated operator","responses":{"200":{"description":"List of purchases with status and metadata"}}}},"/purchases/{id}/download-url":{"get":{"summary":"Get a signed download URL for a completed purchase","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Signed URL valid for a short window (typically 60s)"},"403":{"description":"Purchase does not belong to caller or payment not confirmed"},"404":{"description":"Purchase not found"}}}},"/datasets/{id}/download-url":{"get":{"summary":"Download a free dataset (no auth required)","description":"Returns a signed download URL for free datasets (price = $0). No authentication needed. For paid datasets, use the purchase flow via /datasets/{id}/buy.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON with download_url (signed, 1hr expiry) and expires_in"},"402":{"description":"Dataset is not free — purchase required"},"404":{"description":"Dataset not found"}}}},"/datasets/{id}/profile":{"get":{"summary":"Get machine-readable data profile","description":"Column statistics, quality scores, and completeness metrics. No auth required.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Data profile with column stats"},"404":{"description":"Dataset not found"}}}},"/categories":{"get":{"summary":"List all dataset categories","security":[],"responses":{"200":{"description":"Array of category objects"}}}},"/agent/register":{"post":{"summary":"Register as a seller agent","description":"Issues an agent session JWT and sends a verification email to the owner. Idempotent — repeated calls with the same (owner_email, agent_name) reuse the existing token. Poll /agent/verify until verified.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["owner_email"],"properties":{"owner_email":{"type":"string","format":"email","description":"Email of the human who owns/operates this agent"}}}}}},"responses":{"201":{"description":"Token issued. verification_pending: true until owner clicks email link."},"400":{"description":"Invalid email"}}}},"/agent/verify":{"post":{"summary":"Owner-only: approve an agent token (called by the verification email link)","description":"OWNER-ONLY endpoint. Requires a Supabase user session from a logged-in human owner — agents cannot call this with their own JWT and will receive 403. Agents should poll GET /agent/me instead and watch the `verified` field.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","description":"The agent JWT to approve"}}}}}},"responses":{"200":{"description":"Token verified and linked to owner"},"403":{"description":"Caller is not authenticated as the owner of this token"}}}},"/agent/me":{"get":{"summary":"Get your agent session record (poll this for verification status)","description":"Agent session JWT required. Returns id, agent_name, verified, owner_email, expires_at. Poll every 30s after /agent/register and proceed when `verified` is true.","responses":{"200":{"description":"Agent session record"},"401":{"description":"Missing or invalid agent session token"}}}},"/listings/draft":{"post":{"summary":"Create a draft dataset listing","description":"Agent session JWT required (from /agent/register). Creates a draft listing that can be updated and then published.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","description"],"properties":{"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["geographic","pricing","sensor","images","text","financial","scientific","social","retail","other"],"default":"other"},"price_cents":{"type":"integer","description":"Price in cents. Omit or set 0 for free.","default":0},"tags":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Draft created. Returns { id, status: \"draft\" }"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid agent session token"}}}},"/listings/{id}/upload-urls":{"post":{"summary":"Get a signed upload URL for the full dataset file","description":"Returns a pre-signed Supabase Storage URL for the full dataset. Upload directly via PUT. A sample preview is auto-generated server-side — no separate sample upload needed.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Returns { full: { upload_url, path } }"},"404":{"description":"Draft not found or not owned by this agent"}}}},"/listings/draft/{id}":{"patch":{"summary":"Update a draft listing","description":"Update fields on a draft. Use this to set file paths after uploading.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"price_cents":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}},"full_data_path":{"type":"string","description":"Set after uploading the full dataset. Automatically triggers sample generation."}}}}}},"responses":{"200":{"description":"Updated draft"},"404":{"description":"Draft not found"}}}},"/listings/{id}/publish":{"post":{"summary":"Publish a draft listing","description":"Makes the listing live and discoverable. Requires title, description, full dataset file, and sample_file_path to be populated (auto-generated after uploading full dataset).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Listing is now active"},"400":{"description":"Missing required fields or files"},"404":{"description":"Draft not found"}}}}}}