{
  "openapi": "3.1.1",
  "info": {
    "title": "Sizewise How Many Fit API",
    "version": "1.0.0",
    "summary": "How many Earths fit in the Sun, golf balls in a room or pallets in a trailer?",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://sizewisefitcount.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "How many Earths fit in the Sun, golf balls in a room or pallets in a trailer?",
        "description": "Counts how many of one thing fit in another by length, by area, by volume (with the packing fractions of real spheres) or as whole boxes stacked in layers, using Wikidata sizes or your own dimensions.\n\nMethodology:\n- Length: the container’s longest known dimension divided by the item’s. Area: rectangles from two dimensions or the cross-section of a round object (π d² ÷ 4). Volume: boxes from three dimensions, spheres from the diameter (π d³ ÷ 6).\n- Round items lose space to gaps: equal spheres fill at most π ÷ (3√2) ≈ 74.05 % (Kepler conjecture, proved by Hales), about 64 % when poured at random (random close packing); circles in a plane at most π ÷ (2√3) ≈ 90.69 %.\n- Whole boxes: for each choice of the upright side, the floor is filled with rows in up to two orientations (all splits tried), and the layers are stacked; the best total wins. Mixed patterns beyond two row orientations are not searched, so the count is a guaranteed lower bound.\n\nReal objects are not perfect spheres or boxes; the counts are geometric. Planets and stars are treated as spheres of their mean or equatorial diameter.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "sizewise_fit_count",
        "x-owner-app": "sizewise",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SizewiseFitCountInput"
              },
              "examples": {
                "example1": {
                  "summary": "Earths in the Sun",
                  "value": {
                    "item": "Earth",
                    "container": "Sun",
                    "mode": "volume",
                    "packing": "none"
                  }
                },
                "example2": {
                  "summary": "EUR-pallets on a 13.6 m trailer floor",
                  "value": {
                    "item": "Pallet load = 1.2 × 0.8 × 1.6 m",
                    "container": "Trailer = 13.6 × 2.48 × 2.7 m",
                    "mode": "boxes",
                    "keepUpright": true
                  }
                },
                "example3": {
                  "summary": "Golf balls in a cubic metre box",
                  "value": {
                    "item": "Golf ball",
                    "container": "Box = 1 × 1 × 1 m",
                    "mode": "volume",
                    "packing": "random"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SizewiseFitCountResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "SizewiseFitCountInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "item": {
            "title": "What to fit",
            "description": "An object from the list, or your own: “Box = 40 × 30 × 20 cm”, “Ball = ⌀ 22 cm” or “Rope = 12 m”.",
            "type": "string",
            "maxLength": 120,
            "default": "Earth"
          },
          "container": {
            "title": "Where to fit it",
            "description": "Same choices as above, for example “Room = 5 × 4 × 2.5 m”.",
            "type": "string",
            "maxLength": 120,
            "default": "Sun"
          },
          "mode": {
            "title": "Count by",
            "type": "string",
            "enum": [
              "volume",
              "area",
              "length",
              "boxes"
            ],
            "default": "volume"
          },
          "packing": {
            "title": "Gaps between round things",
            "type": "string",
            "enum": [
              "none",
              "random",
              "densest"
            ],
            "default": "none"
          },
          "keepUpright": {
            "title": "Keep boxes upright",
            "description": "Whole boxes only: the third dimension stays vertical (pallets, fridges).",
            "type": "boolean",
            "default": false
          }
        },
        "required": []
      },
      "SizewiseFitCountResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}