{
  "openapi": "3.1.0",
  "info": {
    "title": "Garagy supplier API",
    "version": "1.0.0",
    "description": "Keep your Garagy catalogue, stock and prices in step with your own system, and handle your Parts Hub orders. Create a key in Garagy: Selling → Your own system → API push. Money is in fils (1 BHD = 1000 fils), prices exclude VAT."
  },
  "servers": [{ "url": "https://<project>.supabase.co/functions/v1/supplier-api", "description": "Replace <project> with the address shown on the developer page." }],
  "security": [{ "apiKey": [] }],
  "components": {
    "securitySchemes": {
      "apiKey": { "type": "http", "scheme": "bearer", "description": "Authorization: Bearer gk_… (one key per system; revocable by the shop owner)." }
    },
    "schemas": {
      "ItemIn": {
        "type": "object",
        "required": ["sku"],
        "properties": {
          "sku": { "type": "string", "maxLength": 60, "description": "Your part number; matches the item (not case-sensitive)." },
          "name": { "type": "string", "description": "Required for a new item." },
          "name_ar": { "type": "string" },
          "oem_number": { "type": "string" },
          "brand": { "type": "string" },
          "category": { "type": "string" },
          "condition": { "type": "string", "enum": ["new_oem", "new_aftermarket", "used", "refurbished"] },
          "price_fils": { "type": "integer", "minimum": 0, "description": "Shop (retail) price, VAT excluded." },
          "wholesale_price_fils": { "type": "integer", "minimum": 0, "description": "Price for business buyers." },
          "online_price_fils": { "type": "integer", "minimum": 0, "description": "Parts Hub price when different." },
          "list_on_marketplace": { "type": "boolean" },
          "active": { "type": "boolean" },
          "quantity": { "type": "number", "minimum": 0, "description": "Units on hand at the branch (not a change). Cannot go below what open orders hold." },
          "branch": { "type": "string", "description": "Branch (warehouse) name in Garagy; the main branch when left out." },
          "fit": {
            "type": "array",
            "description": "Cars the part fits; replaces the item's list.",
            "items": { "type": "object", "required": ["make", "model"], "properties": { "make": { "type": "string" }, "model": { "type": "string" }, "year_from": { "type": "integer" }, "year_to": { "type": "integer" } } }
          }
        }
      },
      "UpsertResult": {
        "type": "object",
        "properties": {
          "received": { "type": "integer" }, "saved": { "type": "integer" }, "created": { "type": "integer" }, "updated": { "type": "integer" },
          "errors": { "type": "array", "items": { "type": "object", "properties": { "index": { "type": "integer" }, "sku": { "type": ["string", "null"] }, "error": { "type": "string" } } } }
        }
      },
      "Error": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } } }
    }
  },
  "paths": {
    "/v1/items": {
      "get": {
        "summary": "Your catalogue as Garagy holds it, by SKU",
        "parameters": [
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 200, "maximum": 500 } }
        ],
        "responses": { "200": { "description": "Items with stock per branch, reserved units and fit." }, "401": { "description": "Invalid or revoked key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }
      },
      "post": {
        "summary": "Create or update up to 1,000 items",
        "description": "Idempotent by SKU: sending the same rows again changes nothing. Each row is saved or reported on its own.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "maxItems": 1000, "items": { "$ref": "#/components/schemas/ItemIn" } } } } } } },
        "responses": { "200": { "description": "Saved; rejected rows in errors", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpsertResult" } } } }, "413": { "description": "Body over 2 MB" }, "422": { "description": "The whole call was refused (e.g. the business is read-only)" } }
      }
    },
    "/v1/orders": {
      "get": {
        "summary": "Your Parts Hub orders",
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["placed", "confirmed", "ready", "out_for_delivery", "delivered", "cancelled", "all"], "default": "placed" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 100, "maximum": 500 } }
        ],
        "responses": { "200": { "description": "Orders with lines (SKU, quantity, price), delivery and payout amounts." } }
      }
    },
    "/v1/orders/{order}/{action}": {
      "post": {
        "summary": "Move an order, as in the Garagy portal",
        "parameters": [
          { "name": "order", "in": "path", "required": true, "schema": { "type": "string", "example": "ORD-2026-000123" } },
          { "name": "action", "in": "path", "required": true, "schema": { "type": "string", "enum": ["confirm_fitment", "accept", "reject", "ready", "dispatched", "delivered"] } }
        ],
        "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "reason": { "type": "string", "description": "Required for reject; the buyer sees it." } } } } } },
        "responses": { "200": { "description": "The order's new status" }, "404": { "description": "Not your order" }, "422": { "description": "Not allowed from the order's current status" } }
      }
    }
  }
}
