{
  "openapi": "3.1.0",
  "info": {
    "title": "Liffey Chemicals public API",
    "version": "1.0.0",
    "summary": "Catalogue, hazard and transport data, countries served and quote requests for precious-metal compounds made in Dublin, Ireland.",
    "description": "Liffey Chemicals manufactures silver, gold, palladium and platinum compounds in Dublin, Ireland, from metal refined by Liffey Metals, and supplies them by quotation to research, analytical and industrial laboratories in Ireland, every EU member state and Northern Ireland. Every lot ships with a certificate of analysis giving the metal assay; safety data sheets are available for every product. No authentication. Read endpoints are cached for ten minutes and return 503 with Retry-After instead of stale data when the catalogue is unavailable. Human documentation: https://liffeychemicals.com/for-ai. MCP server: https://liffeychemicals.com/mcp.",
    "contact": {
      "name": "Liffey Chemicals",
      "email": "andrew@liffeymetals.com",
      "url": "https://liffeychemicals.com/contact"
    },
    "termsOfService": "https://liffeychemicals.com/terms"
  },
  "servers": [
    {
      "url": "https://liffeychemicals.com"
    }
  ],
  "tags": [
    {
      "name": "catalogue",
      "description": "Products, CAS numbers, hazard and transport classification, pack sizes."
    },
    {
      "name": "business",
      "description": "Who we are, where we ship, how ordering works."
    },
    {
      "name": "quotes",
      "description": "Request a quotation on a customer's behalf."
    }
  ],
  "paths": {
    "/api/public/catalogue": {
      "get": {
        "tags": [
          "catalogue"
        ],
        "operationId": "listProducts",
        "summary": "Full catalogue as JSON",
        "description": "Every product with CAS, formula, grade, GHS and transport data, pack sizes and SKUs. Prices are included only when the site is in public-pricing mode. Also served at /catalogue.json.",
        "responses": {
          "200": {
            "description": "Catalogue",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Catalogue"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/api/public/products/{key}": {
      "get": {
        "tags": [
          "catalogue"
        ],
        "operationId": "getProduct",
        "summary": "One product by CAS number or slug",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "CAS number (7761-88-8) or product slug (silver-nitrate-7761-88-8).",
            "schema": {
              "type": "string"
            },
            "example": "7761-88-8"
          }
        ],
        "responses": {
          "200": {
            "description": "Product",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "404": {
            "description": "No such product",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/api/public/business": {
      "get": {
        "tags": [
          "business"
        ],
        "operationId": "getBusiness",
        "summary": "Business facts, services, ordering process, endpoints",
        "description": "Name, contact details, service area, pricing mode, how to order, verifiable facts and the list of facts assistants most often get wrong.",
        "responses": {
          "200": {
            "description": "Business facts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/public/countries": {
      "get": {
        "tags": [
          "business"
        ],
        "operationId": "listCountries",
        "summary": "Countries served with VAT treatment, currency and transit times",
        "responses": {
          "200": {
            "description": "Countries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/public/quote-request": {
      "post": {
        "tags": [
          "quotes"
        ],
        "operationId": "requestQuote",
        "summary": "Request a quotation",
        "description": "Creates a quote request exactly as the website form does. The customer receives a receipt by email with a one-click cancel link; we reply within one working day. Limited to 5 requests per hour per IP address.\n\nTerms (accepts_terms must be true): By submitting a quote request you confirm that: (1) the customer is a business, research, analytical or industrial buyer, not a private individual; (2) the customer has agreed to be contacted by Liffey Chemicals by email (and by phone if a number is given) about this request; (3) the contact details are the customer's own and were supplied by them for this purpose; (4) delivery is to Ireland, an EU member state or Northern Ireland; (5) a quotation, when issued, is in euro, exclusive of VAT, valid for 7 days, and is not an order. A receipt is emailed to the customer with a link to cancel the request.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Request recorded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteReceipt"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or terms not accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (Retry-After header)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    }
  },
  "components": {
    "responses": {
      "Unavailable": {
        "description": "Temporarily unavailable; retry after the number of seconds in Retry-After.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "retry_after_seconds": {
            "type": "integer"
          },
          "terms": {
            "type": "string"
          },
          "schema": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "error"
        ]
      },
      "QuoteRequest": {
        "type": "object",
        "required": [
          "contact_name",
          "email",
          "organisation",
          "quantity",
          "accepts_terms"
        ],
        "properties": {
          "contact_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120,
            "description": "Customer's name."
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 200,
            "description": "Customer's own email address; the receipt and quotation go here."
          },
          "organisation": {
            "type": "string",
            "minLength": 2,
            "maxLength": 200,
            "description": "Company, university or institute."
          },
          "phone": {
            "type": "string",
            "maxLength": 40
          },
          "product": {
            "type": "string",
            "maxLength": 120,
            "description": "CAS number or product slug from the catalogue. Omit for a custom compound and describe it in message."
          },
          "quantity": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Free text, e.g. \"4 × 25 g\" or \"2 kg\"."
          },
          "ship_to_country": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 code of the destination; XI for Northern Ireland.",
            "enum": [
              "IE",
              "AT",
              "BE",
              "BG",
              "HR",
              "CY",
              "CZ",
              "DK",
              "EE",
              "FI",
              "FR",
              "DE",
              "GR",
              "HU",
              "IT",
              "LV",
              "LT",
              "LU",
              "MT",
              "NL",
              "PL",
              "PT",
              "RO",
              "SK",
              "SI",
              "ES",
              "SE",
              "XI"
            ]
          },
          "message": {
            "type": "string",
            "maxLength": 2000,
            "description": "Specification, grade, application, documents needed, delivery deadline."
          },
          "accepts_terms": {
            "type": "boolean",
            "const": true,
            "description": "Must be true. The customer has agreed to the terms in this operation's description."
          }
        }
      },
      "QuoteReceipt": {
        "type": "object",
        "properties": {
          "quote_number": {
            "type": "string",
            "example": "LCQ-000123"
          },
          "status": {
            "type": "string",
            "const": "received"
          },
          "product": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "cas": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "ship_to_country": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "reply_time": {
            "type": "string"
          },
          "receipt_sent_to": {
            "type": "string",
            "format": "email"
          },
          "cancel_url": {
            "type": "string",
            "format": "uri"
          },
          "terms": {
            "type": "string"
          }
        }
      },
      "Catalogue": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "prices_public": {
            "type": "boolean"
          },
          "currency": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Product"
            }
          }
        }
      },
      "Product": {
        "type": "object",
        "properties": {
          "cas": {
            "type": "string",
            "example": "7761-88-8"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "formula": {
            "type": "string"
          },
          "molecular_weight_g_mol": {
            "type": [
              "number",
              "null"
            ]
          },
          "metal_content_pct": {
            "type": [
              "number",
              "null"
            ]
          },
          "grade": {
            "type": [
              "string",
              "null"
            ]
          },
          "metal": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "synonyms": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "local_names": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Product name in other EU languages keyed by ISO 639-1 code."
          },
          "ghs": {
            "type": "object",
            "additionalProperties": true
          },
          "transport": {
            "type": "object",
            "additionalProperties": true
          },
          "packs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "sku": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "grams": {
                  "type": "number"
                },
                "availability": {
                  "type": "string"
                },
                "price_eur": {
                  "type": "number"
                }
              }
            }
          },
          "pricing": {
            "type": "object",
            "additionalProperties": true
          },
          "sds_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "quote_url": {
            "type": "string",
            "format": "uri"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "verify_at": {
            "type": "string",
            "format": "uri"
          }
        }
      }
    }
  }
}