{
  "openapi": "3.1.0",
  "info": {
    "title": "wedopeptides API",
    "version": "1.0.0",
    "description": "Public API for wedopeptides. Covers account management, loyalty state sync, payment checkout creation, and health. Authentication uses an HttpOnly session cookie (amp_sess) issued by the signup/login endpoints \u2014 OAuth/OIDC is not supported. A static machine-readable product catalog is available at https://new-dvv.pages.dev/products.json. All peptides are for research use only.",
    "contact": {
      "email": "support@allmypeptides.com",
      "url": "https://new-dvv.pages.dev/contact/"
    }
  },
  "servers": [
    {
      "url": "https://new-dvv.pages.dev"
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "summary": "Service health check",
        "operationId": "getHealth",
        "responses": {
          "200": {
            "description": "Service is up",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "ok"
                    },
                    "time": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/signup": {
      "post": {
        "summary": "Create an account",
        "operationId": "signup",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "password",
                  "firstName",
                  "lastName"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "password": {
                    "type": "string",
                    "minLength": 6
                  },
                  "firstName": {
                    "type": "string"
                  },
                  "lastName": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "referralCode": {
                    "type": "string",
                    "description": "Optional AMPXXXX referral code of an existing customer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account created; session cookie set",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthSuccess"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "description": "Email already registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/login": {
      "post": {
        "summary": "Log in",
        "operationId": "login",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "password"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "password": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logged in; session cookie set",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthSuccess"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/auth/logout": {
      "post": {
        "summary": "Log out (destroys the server session)",
        "operationId": "logout",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Session destroyed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/me": {
      "get": {
        "summary": "Current account profile and loyalty state",
        "operationId": "me",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Profile and loyalty",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthSuccess"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/state/sync": {
      "post": {
        "summary": "Persist profile edits and loyalty state for the logged-in account",
        "description": "Only firstName, lastName and phone may be changed on the profile. Loyalty data is sanitised server-side; email, account id and referral code are immutable.",
        "operationId": "stateSync",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "profile": {
                    "$ref": "#/components/schemas/Profile"
                  },
                  "loyalty": {
                    "$ref": "#/components/schemas/Loyalty"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "State stored",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/create-checkout": {
      "post": {
        "summary": "Save a server-priced order and create its hosted payment session",
        "description": "Same-origin POST. The server saves verified goods, delivery, price, stock reservation and provider identity before returning a payment URL. Send the complete delivery details and an unchanged unique reference when retrying an uncertain request. Only hand off a response with order_saved=true. Do not POST a replacement order to /api/notify. Payment is completed by the human using the hosted URL.",
        "operationId": "createCheckout",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "checkout_reference",
                  "amount",
                  "currency",
                  "paymentMethod",
                  "items",
                  "email",
                  "firstName",
                  "lastName",
                  "address1",
                  "city",
                  "postcode"
                ],
                "properties": {
                  "checkout_reference": {
                    "type": "string",
                    "pattern": "^[A-Z0-9][A-Z0-9_-]{5,79}$"
                  },
                  "amount": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "Server-equivalent order total in GBP, including shipping and eligible discounts, before a separately levied provider card fee."
                  },
                  "subtotal": {
                    "type": "number"
                  },
                  "discountAmount": {
                    "type": "number"
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "GBP"
                    ]
                  },
                  "paymentMethod": {
                    "type": "string",
                    "enum": [
                      "bank",
                      "card",
                      "crypto"
                    ]
                  },
                  "cardProviderShown": {
                    "type": "string"
                  },
                  "cryptoAsset": {
                    "type": "string"
                  },
                  "promoCode": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 254
                  },
                  "firstName": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "lastName": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "phone": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "address1": {
                    "type": "string",
                    "maxLength": 180
                  },
                  "address2": {
                    "type": "string",
                    "maxLength": 180
                  },
                  "city": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "postcode": {
                    "type": "string",
                    "maxLength": 16
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "items": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 50,
                    "items": {
                      "type": "object",
                      "required": [
                        "productId",
                        "size",
                        "quantity"
                      ],
                      "properties": {
                        "productId": {
                          "type": "string"
                        },
                        "size": {
                          "type": "string"
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 999
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Durable order and recorded payment session. Only hand off when order_saved is true.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "order_saved",
                    "hosted_checkout_url",
                    "checkout_reference"
                  ],
                  "properties": {
                    "order_saved": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "hosted_checkout_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "checkout_reference": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input. No provider handoff."
          },
          "403": {
            "description": "Foreign or missing Origin refused."
          },
          "409": {
            "description": "Changed basket/provider/stock/promo, or an existing/expired checkout. Show the code and ask for review. Do not automatically start another charge."
          },
          "503": {
            "description": "Saving or provider verification failed. An uncertain provider attempt retains its reference; retry the same request."
          }
        }
      }
    },
    "/api/stock": {
      "get": {
        "summary": "Live stock levels for limited SKUs",
        "description": "Quantities for SKUs the shop tracks a limited stock count for. SKUs absent from the response are not stock-limited. Keys are of the form <product>-<size>, e.g. bpc-157-10mg.",
        "operationId": "getStock",
        "tags": [
          "Catalogue"
        ],
        "responses": {
          "200": {
            "description": "Map of SKU to remaining quantity",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "example": {
                  "retatrutide-30mg": 4,
                  "mots-c-40mg": 2,
                  "mots-c-10mg": 10
                }
              }
            }
          }
        }
      }
    },
    "/api/validate-promo": {
      "get": {
        "summary": "Validate a discount code",
        "description": "Checks whether a promotional code is currently valid and returns its discount as a decimal fraction (0.10 = 10% off). Does not consume the code.",
        "operationId": "validatePromo",
        "tags": [
          "Checkout"
        ],
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "AMP10"
          }
        ],
        "responses": {
          "200": {
            "description": "Validation result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "code": {
                      "type": "string"
                    },
                    "discount": {
                      "type": "number",
                      "description": "Decimal fraction, e.g. 0.1 for 10%"
                    }
                  },
                  "required": [
                    "valid"
                  ]
                },
                "example": {
                  "valid": true,
                  "code": "AMP10",
                  "discount": 0.1
                }
              }
            }
          }
        }
      }
    },
    "/api/version": {
      "get": {
        "summary": "Current deployment build identifier",
        "operationId": "getVersion",
        "tags": [
          "Meta"
        ],
        "responses": {
          "200": {
            "description": "Build identifier for the running deployment",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "build": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "build": "v286-000001-s615"
                }
              }
            }
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "summary": "Search the research-peptide catalogue",
        "description": "Free-text search across product name, category, synonyms and description. Returns the same records as products.json, filtered. All products are supplied for in-vitro research use only.",
        "operationId": "searchCatalogue",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Search term, e.g. 'bpc-157' or 'metabolic'."
          },
          {
            "name": "inStock",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Return only products with stock."
          }
        ],
        "responses": {
          "200": {
            "description": "Matching products"
          },
          "400": {
            "description": "Missing q parameter"
          },
          "503": {
            "description": "Catalogue unavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "amp_sess",
        "description": "HttpOnly session cookie issued by /api/auth/signup or /api/auth/login. Valid 30 days."
      }
    },
    "responses": {
      "Error": {
        "description": "Error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          }
        }
      },
      "Profile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "email": {
            "type": "string",
            "readOnly": true
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "readOnly": true
          },
          "referralCode": {
            "type": "string",
            "readOnly": true
          },
          "referredBy": {
            "type": "string",
            "readOnly": true
          }
        }
      },
      "Loyalty": {
        "type": "object",
        "properties": {
          "points": {
            "type": "integer",
            "minimum": 0
          },
          "lifetimePoints": {
            "type": "integer",
            "minimum": 0
          },
          "tier": {
            "type": "string",
            "enum": [
              "bronze",
              "silver",
              "gold",
              "platinum"
            ]
          },
          "pointsHistory": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "availableRewards": {
            "type": "array",
            "items": {}
          },
          "redeemedRewards": {
            "type": "array",
            "items": {}
          }
        }
      },
      "AuthSuccess": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "user": {
            "type": "object",
            "properties": {
              "profile": {
                "$ref": "#/components/schemas/Profile"
              }
            }
          },
          "loyalty": {
            "$ref": "#/components/schemas/Loyalty"
          }
        }
      }
    }
  }
}
