{
  "openapi": "3.1.0",
  "info": {
    "title": "SupplierSpy Benchmark API",
    "description": "Independent, algorithmically-scored benchmark of top dropshipping supplier platforms. No paid rankings. Licensed CC BY 4.0.",
    "version": "1.0",
    "contact": {
      "name": "D.B. Shadow",
      "email": "hello@supplierspy.com",
      "url": "https://supplierspy.com/about"
    },
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    },
    "x-data-version": "2026-04-17",
    "x-supplier-count": 17
  },
  "servers": [
    {
      "url": "https://supplierspy.com",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "summary": "Service health probe",
        "description": "Lightweight check returning service metadata and dataset version. Useful for uptime monitoring and cache-busting clients.",
        "operationId": "getHealth",
        "tags": [
          "meta"
        ],
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/leaderboard": {
      "get": {
        "summary": "Full ranked leaderboard (JSON)",
        "description": "Returns all suppliers ranked by their overall score, along with the scoring weights used to compute it.",
        "operationId": "getLeaderboard",
        "tags": [
          "leaderboard"
        ],
        "responses": {
          "200": {
            "description": "Leaderboard with weights",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Leaderboard"
                }
              }
            }
          }
        }
      }
    },
    "/api/leaderboard.csv": {
      "get": {
        "summary": "Full ranked leaderboard (CSV)",
        "description": "Same leaderboard as the JSON endpoint, but flattened to one row per supplier with all 8 dimension scores as columns. Scores are integer-rounded.",
        "operationId": "getLeaderboardCsv",
        "tags": [
          "leaderboard"
        ],
        "responses": {
          "200": {
            "description": "CSV download",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "example": "rank,slug,name,score,review_score,pricing_transparency,business_transparency,shipping_clarity,product_range,access,support,integration\n1,yakkyo,Yakkyo,92,84,100,100,88,94,92,82,86"
                }
              }
            }
          }
        }
      }
    },
    "/api/supplier/{slug}": {
      "get": {
        "summary": "Full supplier profile",
        "description": "Complete supplier record plus `overall_score` and `rank` fields computed from the current dataset.",
        "operationId": "getSupplier",
        "tags": [
          "supplier"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Supplier slug, lowercase, hyphenated (e.g. `yakkyo`, `shopify-collective`).",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Supplier profile with rank",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Supplier"
                }
              }
            }
          },
          "404": {
            "description": "Unknown slug",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "example": {
                    "error": "not found"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/latest": {
      "get": {
        "summary": "Latest KV snapshot",
        "description": "The most recent leaderboard snapshot produced by the refresh pipeline. Used by the header countdown and the public \"movers\" ticker.",
        "operationId": "getLatest",
        "tags": [
          "leaderboard"
        ],
        "responses": {
          "200": {
            "description": "Latest snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "timestamp",
                    "leaderboard"
                  ],
                  "properties": {
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "next_refresh_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "leaderboard": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "movers": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "spike_detected": {
                      "type": "boolean"
                    },
                    "sites_healthy": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No snapshot has been written yet"
          }
        }
      }
    },
    "/api/refresh": {
      "post": {
        "summary": "Trigger a refresh run (admin)",
        "description": "Runs the full refresh pipeline and writes a new KV snapshot. Requires a bearer token that matches `REFRESH_TOKEN` env secret.",
        "operationId": "postRefresh",
        "tags": [
          "admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Refresh completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "snapshot": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "503": {
            "description": "Refresh endpoint not configured on this deploy"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "opaque",
        "description": "Bearer token from the `REFRESH_TOKEN` env secret."
      }
    },
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "required": [
          "ok",
          "service",
          "data_version",
          "supplier_count",
          "timestamp"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "service": {
            "type": "string",
            "example": "supplierspy"
          },
          "data_version": {
            "type": "string",
            "example": "2026-04-17"
          },
          "supplier_count": {
            "type": "integer",
            "example": 17
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Leaderboard": {
        "type": "object",
        "required": [
          "data_version",
          "weights",
          "leaderboard"
        ],
        "properties": {
          "data_version": {
            "type": "string",
            "example": "2026-04-17"
          },
          "weights": {
            "type": "object",
            "description": "Dimension weights used to compute the overall score. Sums to 100.",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "leaderboard": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "rank",
                "slug",
                "name",
                "score"
              ],
              "properties": {
                "rank": {
                  "type": "integer"
                },
                "slug": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "score": {
                  "type": "number",
                  "description": "Overall score, 0-100."
                },
                "tagline": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Supplier": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "website",
          "overall_score",
          "rank"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "product_name": {
            "type": "string"
          },
          "website": {
            "type": "string",
            "format": "uri"
          },
          "tagline": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "shipping_origins": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "product_categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pricing": {
            "type": "object",
            "properties": {
              "free_plan": {
                "type": "boolean"
              },
              "starting_price": {
                "type": "string"
              },
              "note": {
                "type": "string"
              }
            }
          },
          "business_transparency": {
            "type": "object",
            "properties": {
              "public_company": {
                "oneOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              "market": {
                "type": "string"
              },
              "isin": {
                "type": "string"
              },
              "ticker": {
                "type": "string"
              },
              "legal_entity": {
                "type": "string"
              },
              "audited_annual_report": {
                "type": "boolean"
              },
              "founders": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "founded": {
                "type": "integer"
              }
            }
          },
          "badges": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "tone": {
                  "type": "string"
                }
              }
            }
          },
          "best_for": {
            "type": "string"
          },
          "heads_up": {
            "type": "string"
          },
          "scores": {
            "type": "object",
            "description": "Raw 0-100 dimension scores.",
            "properties": {
              "reviewScore": {
                "type": "number"
              },
              "pricingTransparency": {
                "type": "number"
              },
              "businessTransparency": {
                "type": "number"
              },
              "shippingClarity": {
                "type": "number"
              },
              "productRange": {
                "type": "number"
              },
              "access": {
                "type": "number"
              },
              "support": {
                "type": "number"
              },
              "integration": {
                "type": "number"
              }
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "overall_score": {
            "type": "number"
          },
          "rank": {
            "type": "integer"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "leaderboard",
      "description": "Ranked supplier data"
    },
    {
      "name": "supplier",
      "description": "Per-supplier detail"
    },
    {
      "name": "meta",
      "description": "Service metadata"
    },
    {
      "name": "admin",
      "description": "Token-protected operations"
    }
  ],
  "externalDocs": {
    "description": "Methodology: how the overall score is computed",
    "url": "https://supplierspy.com/how-we-score"
  }
}