{
  "openapi": "3.1.0",
  "info": {
    "title": "Nexbid API",
    "version": "0.1.0",
    "description": "Open product discovery and attribution API for AI agents. Search products, run auctions, and track conversions through Nexbid's agentic commerce infrastructure.",
    "contact": {
      "name": "Nexbid",
      "url": "https://nexbid.dev"
    },
    "license": {
      "name": "MIT",
      "url": "https://github.com/digital-opua/nexbid/blob/main/LICENSE"
    }
  },
  "servers": [
    {
      "url": "https://api.nexbid.dev",
      "description": "Discovery API (Production)"
    },
    {
      "url": "https://attr.nexbid.dev",
      "description": "Attribution API (Production)"
    }
  ],
  "security": [
    {
      "apiKeyHeader": []
    },
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Discovery",
      "description": "Product search and feed management"
    },
    {
      "name": "Attribution",
      "description": "Click tracking and conversion attribution"
    },
    {
      "name": "System",
      "description": "Health checks and diagnostics"
    }
  ],
  "paths": {
    "/v1/discover": {
      "post": {
        "operationId": "discoverProducts",
        "tags": [
          "Discovery"
        ],
        "summary": "Search products",
        "description": "Search the Nexbid product index using natural language queries. Returns organic results and optionally a sponsored product from the real-time auction.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DiscoverRequest"
              },
              "example": {
                "query": "running shoes under 200 CHF",
                "intent": "purchase",
                "budget": {
                  "maxCents": 20000,
                  "currency": "CHF"
                },
                "geo": "CH",
                "maxResults": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Products found (may include sponsored result from auction)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscoverResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (missing query, query too long)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "missingQuery": {
                    "value": {
                      "error": "Field \"query\" is required (non-empty string)",
                      "code": "missing_query"
                    }
                  },
                  "queryTooLong": {
                    "value": {
                      "error": "Field \"query\" must be 500 characters or less",
                      "code": "query_too_long"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "missingKey": {
                    "value": {
                      "error": "API key required",
                      "code": "missing_api_key"
                    }
                  },
                  "invalidKey": {
                    "value": {
                      "error": "Invalid API key",
                      "code": "invalid_api_key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API key revoked or insufficient permissions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "revoked": {
                    "value": {
                      "error": "API key has been revoked",
                      "code": "api_key_revoked"
                    }
                  },
                  "noPermission": {
                    "value": {
                      "error": "API key lacks discover permission",
                      "code": "insufficient_permissions"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/feeds": {
      "post": {
        "operationId": "createFeed",
        "tags": [
          "Discovery"
        ],
        "summary": "Register a product feed",
        "description": "Register a new product feed for ingestion. Supported formats: Google Shopping XML, JSON, CSV.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FeedCreateRequest"
              },
              "example": {
                "advertiserId": "adv_123",
                "feedUrl": "https://shop.example.com/feed.xml",
                "feedType": "google_shopping_xml",
                "name": "Main Product Feed",
                "geoScope": [
                  "CH",
                  "DE"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Feed created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "description": "Feed already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/click": {
      "post": {
        "operationId": "generateClickUrl",
        "tags": [
          "Attribution"
        ],
        "summary": "Generate attributed click URL",
        "description": "Generate a product URL decorated with `ad_*` attribution parameters. The click ID (UUID v7) enables conversion tracking back to the original agent query.",
        "servers": [
          {
            "url": "https://attr.nexbid.dev"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClickRequest"
              },
              "example": {
                "productId": "prod_abc123",
                "feedId": "feed_xyz",
                "queryId": "q_test123",
                "agent": "claude_computer_use",
                "targetUrl": "https://shop.example.com/product/123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Attributed URL generated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClickResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (missing fields, invalid URL)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/track": {
      "post": {
        "operationId": "trackConversion",
        "tags": [
          "Attribution"
        ],
        "summary": "Track a conversion event",
        "description": "Record a conversion event (impression, click, add_to_cart, purchase). For billable events (click, purchase), triggers revenue share calculation and atomic budget decrement.",
        "servers": [
          {
            "url": "https://attr.nexbid.dev"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TrackRequest"
              },
              "example": {
                "event": {
                  "ad_click_id": "0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
                  "ad_conversion": "purchase",
                  "ad_revenue": 15900,
                  "ad_currency": "CHF",
                  "ad_product_id": "prod_abc123"
                },
                "meta": {
                  "shopUrl": "https://shop.example.com",
                  "orderId": "ORD-2026-001"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event recorded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrackResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid event data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/health": {
      "get": {
        "operationId": "healthCheck",
        "tags": [
          "System"
        ],
        "summary": "Health check",
        "description": "Check API and database health status. No authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service degraded (database unreachable)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key provided via x-api-key header"
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key provided as Bearer token"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "API key revoked or insufficient permissions",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "DiscoverRequest": {
        "type": "object",
        "required": [
          "query"
        ],
        "properties": {
          "query": {
            "type": "string",
            "maxLength": 500,
            "description": "Natural language product query"
          },
          "intent": {
            "type": "string",
            "enum": [
              "purchase",
              "compare",
              "research",
              "browse"
            ]
          },
          "budget": {
            "type": "object",
            "properties": {
              "maxCents": {
                "type": "integer",
                "description": "Maximum price in cents"
              },
              "minCents": {
                "type": "integer",
                "description": "Minimum price in cents"
              },
              "currency": {
                "type": "string",
                "enum": [
                  "CHF",
                  "EUR",
                  "USD",
                  "GBP"
                ]
              }
            }
          },
          "geo": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code",
            "default": "CH"
          },
          "category": {
            "type": "string",
            "description": "Filter by product category"
          },
          "brand": {
            "type": "string",
            "description": "Filter by brand name"
          },
          "maxResults": {
            "type": "integer",
            "minimum": 1,
            "maximum": 50,
            "default": 10
          }
        }
      },
      "DiscoverResponse": {
        "type": "object",
        "properties": {
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductResult"
            },
            "description": "Organic search results ranked by relevance"
          },
          "sponsored": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SponsoredProduct"
              },
              {
                "type": "null"
              }
            ],
            "description": "Auction winner (sponsored product) or null if no auction ran"
          },
          "auction": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AuctionResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Auction metadata (null if auction disabled or no participants)"
          },
          "meta": {
            "type": "object",
            "properties": {
              "totalMatches": {
                "type": "integer",
                "description": "Total matching products (before limit)"
              },
              "latencyMs": {
                "type": "integer",
                "description": "Total response time including auction"
              },
              "cached": {
                "type": "boolean"
              },
              "auctionEvaluated": {
                "type": "boolean",
                "description": "Whether auction was evaluated for this query"
              },
              "version": {
                "type": "string"
              }
            }
          }
        }
      },
      "ProductResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "imageUrl": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "price": {
            "type": "object",
            "properties": {
              "amount": {
                "type": "integer",
                "description": "Price in smallest currency unit (cents)"
              },
              "currency": {
                "type": "string",
                "enum": [
                  "CHF",
                  "EUR",
                  "USD",
                  "GBP"
                ]
              }
            }
          },
          "category": {
            "type": "string",
            "nullable": true
          },
          "brand": {
            "type": "string",
            "nullable": true
          },
          "availability": {
            "type": "string",
            "enum": [
              "in_stock",
              "out_of_stock",
              "preorder"
            ]
          },
          "score": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Relevance score"
          }
        }
      },
      "SponsoredProduct": {
        "description": "Auction-winning product injected as sponsored result",
        "allOf": [
          {
            "$ref": "#/components/schemas/ProductResult"
          },
          {
            "type": "object",
            "properties": {
              "campaignId": {
                "type": "string",
                "format": "uuid",
                "description": "Winning campaign ID"
              },
              "bidCents": {
                "type": "integer",
                "description": "Winning bid in cents"
              },
              "auctionScore": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "description": "Composite auction score"
              },
              "sponsored": {
                "type": "boolean",
                "const": true
              }
            },
            "required": [
              "campaignId",
              "bidCents",
              "auctionScore",
              "sponsored"
            ]
          }
        ]
      },
      "AuctionResult": {
        "type": "object",
        "description": "Real-time first-price sealed-bid auction result",
        "properties": {
          "queryId": {
            "type": "string",
            "format": "uuid"
          },
          "query": {
            "type": "string"
          },
          "geo": {
            "type": "string"
          },
          "winnerCampaignId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "winnerProductId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "winningBidCents": {
            "type": "integer",
            "nullable": true
          },
          "secondBidCents": {
            "type": "integer",
            "nullable": true,
            "description": "Second-highest bid (for analytics)"
          },
          "auctionScore": {
            "type": "number",
            "nullable": true,
            "description": "Winner composite score (0.3·bid + 0.3·similarity + 0.2·quality + 0.2·context)"
          },
          "participantCount": {
            "type": "integer",
            "description": "Number of eligible auction participants"
          },
          "latencyMs": {
            "type": "integer",
            "description": "Auction engine latency"
          }
        }
      },
      "FeedCreateRequest": {
        "type": "object",
        "required": [
          "advertiserId",
          "feedUrl",
          "feedType"
        ],
        "properties": {
          "advertiserId": {
            "type": "string"
          },
          "feedUrl": {
            "type": "string",
            "format": "uri"
          },
          "feedType": {
            "type": "string",
            "enum": [
              "google_shopping_xml",
              "json",
              "csv"
            ]
          },
          "name": {
            "type": "string"
          },
          "updateInterval": {
            "type": "integer",
            "default": 360,
            "description": "Minutes between updates"
          },
          "geoScope": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "default": [
              "CH"
            ]
          }
        }
      },
      "FeedCreateResponse": {
        "type": "object",
        "properties": {
          "feed": {
            "$ref": "#/components/schemas/Feed"
          },
          "ingestionStarted": {
            "type": "boolean"
          }
        }
      },
      "Feed": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "advertiserId": {
            "type": "string"
          },
          "feedUrl": {
            "type": "string"
          },
          "feedType": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "updateInterval": {
            "type": "integer"
          },
          "geoScope": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lastSyncedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "productCount": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "active",
              "error",
              "paused"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ClickRequest": {
        "type": "object",
        "required": [
          "productId",
          "feedId",
          "queryId",
          "agent",
          "targetUrl"
        ],
        "properties": {
          "productId": {
            "type": "string",
            "description": "Product ID from the feed"
          },
          "feedId": {
            "type": "string",
            "description": "Feed identifier"
          },
          "queryId": {
            "type": "string",
            "description": "Agent query ID that led to this click"
          },
          "agent": {
            "type": "string",
            "enum": [
              "openai_operator",
              "claude_computer_use",
              "google_gemini",
              "custom"
            ],
            "description": "Agent type triggering the interaction"
          },
          "targetUrl": {
            "type": "string",
            "format": "uri",
            "description": "Product URL to decorate with attribution params"
          }
        }
      },
      "ClickResponse": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Decorated URL with ad_* attribution parameters"
          },
          "clickId": {
            "type": "string",
            "description": "UUID v7 click ID (time-sortable)"
          },
          "params": {
            "$ref": "#/components/schemas/AttributionParams"
          }
        }
      },
      "AttributionParams": {
        "type": "object",
        "description": "Attribution parameters appended as URL query params (ad_* prefix)",
        "properties": {
          "ad_click_id": {
            "type": "string",
            "description": "UUID v7 click ID"
          },
          "ad_product_id": {
            "type": "string"
          },
          "ad_feed_id": {
            "type": "string"
          },
          "ad_query_id": {
            "type": "string"
          },
          "ad_source": {
            "type": "string",
            "const": "nexbid_discovery"
          },
          "ad_agent": {
            "type": "string",
            "enum": [
              "openai_operator",
              "claude_computer_use",
              "google_gemini",
              "custom"
            ]
          }
        }
      },
      "TrackRequest": {
        "type": "object",
        "required": [
          "event"
        ],
        "properties": {
          "event": {
            "type": "object",
            "required": [
              "ad_click_id",
              "ad_conversion"
            ],
            "properties": {
              "ad_click_id": {
                "type": "string",
                "description": "Click ID from the original attribution"
              },
              "ad_conversion": {
                "type": "string",
                "enum": [
                  "impression",
                  "click",
                  "add_to_cart",
                  "purchase"
                ]
              },
              "ad_revenue": {
                "type": "integer",
                "description": "Revenue in cents (required for purchases)"
              },
              "ad_currency": {
                "type": "string",
                "enum": [
                  "CHF",
                  "EUR",
                  "USD",
                  "GBP"
                ]
              },
              "ad_product_id": {
                "type": "string",
                "description": "Product ID (may differ from original for cross-sell)"
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "shopUrl": {
                "type": "string",
                "description": "Shop URL where conversion happened"
              },
              "orderId": {
                "type": "string",
                "description": "Advertiser order ID"
              }
            }
          }
        }
      },
      "TrackResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "eventId": {
            "type": "string",
            "description": "Server-generated event ID"
          },
          "revenueShare": {
            "type": "object",
            "nullable": true,
            "description": "Revenue share breakdown (only for billable events)",
            "properties": {
              "publisherShareCents": {
                "type": "integer"
              },
              "platformFeeCents": {
                "type": "integer"
              },
              "revenueSharePct": {
                "type": "number",
                "description": "Publisher share fraction (e.g. 0.7 = 70%)"
              }
            }
          },
          "remainingBudgetCents": {
            "type": "integer",
            "nullable": true,
            "description": "Remaining campaign budget after decrement"
          }
        }
      },
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "degraded"
            ]
          },
          "service": {
            "type": "string",
            "description": "Service name (nexbid-discovery or nexbid-attribution)"
          },
          "version": {
            "type": "string"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable error message"
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error code",
            "enum": [
              "missing_api_key",
              "invalid_api_key",
              "api_key_revoked",
              "insufficient_permissions",
              "missing_query",
              "query_too_long",
              "invalid_body",
              "method_not_allowed",
              "db_error"
            ]
          }
        }
      }
    }
  }
}