{
  "openapi": "3.1.0",
  "info": {
    "title": "UpgradePrinting API",
    "version": "1.0.0",
    "description": "Public API for UpgradePrinting – Professional 3D Printing & Rapid Prototyping Service in Cologne, Germany. Allows automated inquiry submission and client upload token generation.",
    "contact": {
      "name": "UpgradePrinting Support",
      "email": "info@upgradeprinting.de",
      "url": "https://www.upgradeprinting.de"
    }
  },
  "servers": [
    {
      "url": "https://www.upgradeprinting.de",
      "description": "Production Server"
    }
  ],
  "paths": {
    "/api/contact": {
      "post": {
        "summary": "Submit a 3D printing inquiry or message",
        "description": "Sends a contact inquiry with customer contact details, optional material preference, message, and uploaded file attachments.",
        "operationId": "submitContactForm",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Inquiry successfully submitted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error in request payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Request origin not permitted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Method Not Allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (5 requests per 15 minutes).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server processing error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Notification delivery channels failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/blob-upload": {
      "post": {
        "summary": "Generate client-side upload token for 3D model/file attachments",
        "description": "Provides secure upload tokens to upload 3D models (.stl, .step, images, pdf) directly to private Vercel Blob storage for contact submissions.",
        "operationId": "generateBlobUploadToken",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Blob upload authorization issued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Upload configuration or validation failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Request origin not permitted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Method Not Allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Blob storage service not configured.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "summary": "Get OpenAPI 3.1 specification",
        "description": "Returns the machine-readable OpenAPI specification for UpgradePrinting.",
        "operationId": "getOpenApiSpec",
        "responses": {
          "200": {
            "description": "OpenAPI specification.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "summary": "Get LLMs discovery context index",
        "description": "Returns structured markdown context for LLMs and AI agents per the llmstxt.org specification.",
        "operationId": "getLlmsTxt",
        "responses": {
          "200": {
            "description": "llms.txt markdown document.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ContactSubmission": {
        "type": "object",
        "required": ["name", "email", "message"],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Sender's full name",
            "example": "Max Mustermann"
          },
          "email": {
            "type": "string",
            "format": "email",
            "minLength": 3,
            "maxLength": 254,
            "description": "Valid email address for inquiry response",
            "example": "max@example.com"
          },
          "phone": {
            "type": "string",
            "maxLength": 50,
            "description": "Optional telephone number for quick consultation",
            "example": "+49 171 1234567"
          },
          "material": {
            "type": "string",
            "description": "Preferred 3D printing material",
            "enum": ["PLA", "PETG", "ABS", "ASA", "TPU", "Resin", "Noch unklar / Beratung gewünscht"],
            "example": "PETG"
          },
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "description": "Description of the 3D printing project or request",
            "example": "Ich benötige ein passgenaues Gehäuse für ein Elektronikprojekt gedruckt in schwarzem PETG."
          },
          "files": {
            "type": "array",
            "maxItems": 7,
            "description": "List of uploaded file attachments stored in Vercel Blob",
            "items": {
              "$ref": "#/components/schemas/ContactFileAttachment"
            }
          }
        }
      },
      "ContactFileAttachment": {
        "type": "object",
        "required": ["pathname"],
        "properties": {
          "pathname": {
            "type": "string",
            "maxLength": 250,
            "description": "Storage pathname starting with 'contact/'",
            "example": "contact/uuid-part.stl"
          },
          "filename": {
            "type": "string",
            "maxLength": 120,
            "description": "Original file name",
            "example": "part.stl"
          },
          "contentType": {
            "type": "string",
            "description": "MIME content type of attachment",
            "example": "model/stl"
          }
        }
      },
      "ContactSuccessResponse": {
        "type": "object",
        "required": ["message"],
        "properties": {
          "message": {
            "type": "string",
            "example": "Anfrage erfolgreich gesendet."
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["error", "code", "message"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Localized human-readable error description",
            "example": "Ungültige Formulardaten."
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error classification code",
            "example": "VALIDATION_ERROR"
          },
          "message": {
            "type": "string",
            "description": "Detailed English explanation of the error",
            "example": "Validation failed: please check required fields."
          },
          "hint": {
            "type": "string",
            "description": "Actionable resolution recommendation for clients and agents",
            "example": "Ensure name (1-100 chars), valid email, and message (1-2000 chars) are provided."
          }
        }
      }
    }
  }
}
