{
  "openapi": "3.1.0",
  "info": {
    "title": "Hark Tech 3D printing quotes",
    "version": "1.0.0",
    "summary": "Look up live UK 3D printing prices for catalogue models.",
    "description": "Hark Tech (Basingstoke, UK) prints catalogue models and customers' own files and posts them across the UK. These read-only endpoints let AI assistants find a model and get its price, postage, dispatch time and an order link. Never place orders or take payment on a person's behalf: give them order_url. Rate limit: 120 requests per 10 minutes per address. Human-readable guide: https://harktech.co.uk/for-ai-assistants.html An MCP server with the same tools is at https://harktech.co.uk/mcp.",
    "contact": {
      "name": "Hark Tech",
      "url": "https://harktech.co.uk/contact.html"
    }
  },
  "servers": [
    {
      "url": "https://harktech.co.uk"
    }
  ],
  "paths": {
    "/api/quote": {
      "get": {
        "operationId": "getModelQuote",
        "summary": "Price a Printables or Thingiverse model",
        "description": "Indicative price for one copy of the model's main file, from a real slice, plus postage, lead times, batch discounts and an order link. Only models whose licence allows commercial printing are priced; others return available=false with a reason. For a person's own STL/3MF/STEP file, send them to https://harktech.co.uk/printing.html instead.",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Printables (printables.com/model/123), Thingiverse (thingiverse.com/thing:123) or harktech.co.uk/m/ model link. Alternatively give site and id."
          },
          {
            "name": "site",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "printables",
                "thingiverse"
              ]
            }
          },
          {
            "name": "id",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+$"
            }
          },
          {
            "name": "material",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "pla",
              "enum": [
                "pla",
                "pla matte",
                "pla silk",
                "petg",
                "tpu",
                "abs",
                "asa",
                "pc",
                "nylon",
                "petg-cf",
                "pa-cf"
              ]
            }
          },
          {
            "name": "qty",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 999,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A quote (available=true) or an explanation why the model cannot be priced (available=false).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            }
          },
          "400": {
            "description": "Unrecognised model link or material."
          },
          "404": {
            "description": "Model not in the Hark Tech catalogue."
          },
          "429": {
            "description": "Rate limited; retry later."
          },
          "503": {
            "description": "Pricing busy; retry after retry_after_seconds."
          }
        }
      }
    },
    "/api/models/search": {
      "get": {
        "operationId": "searchModels",
        "summary": "Search the model catalogue",
        "description": "Use license=commercial_ok to list only models that /api/quote can price. Pass a result's source_site and source_id to /api/quote as site and id.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "license",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "printable",
              "enum": [
                "all",
                "printable",
                "commercial_ok",
                "personal_only"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 60,
              "default": 24
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results (results[] with source_site, source_id, title, source_url, thumbnail_url, license_class)."
          }
        }
      }
    },
    "/api/service-info": {
      "get": {
        "operationId": "getServiceInfo",
        "summary": "Hark Tech service facts",
        "description": "Order minimums by material, postage options and free-delivery threshold, lead times, batch discounts, materials, licence policy, payment and contact.",
        "responses": {
          "200": {
            "description": "Service facts as JSON."
          }
        }
      }
    },
    "/api/agent/quote-file": {
      "post": {
        "operationId": "quoteOwnFile",
        "summary": "Price a person's own STL/3MF/STEP file from a share link",
        "description": "Downloads the file from a public share link (Google Drive, Dropbox, OneDrive, GitHub, Discord attachments), prices it with Hark Tech's estimator and returns checkout_url: the person's basket on harktech.co.uk with the file priced, where they adjust options, enter delivery details and pay. Nothing is ordered or charged until then. Other hosts are refused: send the person to https://harktech.co.uk/printing.html to upload.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file_url"
                ],
                "properties": {
                  "file_url": {
                    "type": "string"
                  },
                  "material": {
                    "type": "string",
                    "default": "pla"
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 999,
                    "default": 1
                  },
                  "lead_time": {
                    "type": "string",
                    "enum": [
                      "standard",
                      "express",
                      "bulk"
                    ],
                    "default": "standard"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "available=true with summary, price_gbp, unit_price_gbp, dimensions_mm, postage and checkout_url; or available=false with reason and message."
          },
          "400": {
            "description": "Missing or unsupported link, or a catalogue model (use /api/quote)."
          },
          "413": {
            "description": "File too large for the instant quote."
          },
          "415": {
            "description": "The link didn't return an STL, 3MF or STEP file."
          },
          "429": {
            "description": "Rate limited."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Quote": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean"
          },
          "summary": {
            "type": "string",
            "description": "One plain-English sentence suitable to repeat to the person."
          },
          "reason": {
            "type": "string",
            "description": "When available=false, e.g. personal_use_licence, licence_excluded, busy, too_big."
          },
          "message": {
            "type": "string"
          },
          "model": {
            "type": "object",
            "properties": {
              "title": {
                "type": "string"
              },
              "designer": {
                "type": "string"
              },
              "source_url": {
                "type": "string"
              },
              "page_url": {
                "type": "string"
              },
              "licence": {
                "type": "string"
              }
            }
          },
          "material": {
            "type": "string"
          },
          "material_name": {
            "type": "string"
          },
          "price_single_copy_gbp": {
            "type": "number",
            "description": "Price for one copy ordered on its own."
          },
          "at_order_minimum": {
            "type": "boolean",
            "description": "True when that price is the order minimum (small part): extra copies or other small parts share it, so do not multiply by quantity."
          },
          "order_minimum_gbp": {
            "type": "number"
          },
          "priced_file": {
            "type": "string"
          },
          "price_basis": {
            "type": "string"
          },
          "quantity_requested": {
            "type": "integer"
          },
          "quantity_note": {
            "type": [
              "string",
              "null"
            ]
          },
          "other_materials_gbp": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "batch_discounts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "min_copies": {
                  "type": "integer"
                },
                "discount_pct": {
                  "type": "integer"
                }
              }
            }
          },
          "lead_times": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "postage": {
            "type": "object"
          },
          "order_url": {
            "type": "string",
            "description": "Give this link to the person to review options and pay on harktech.co.uk."
          },
          "retry_after_seconds": {
            "type": "integer"
          },
          "currency": {
            "type": "string",
            "const": "GBP"
          }
        }
      }
    }
  }
}
