{
  "openapi": "3.1.1",
  "info": {
    "title": "Tip & Bill Split Calculator API",
    "version": "1.0.0",
    "summary": "Tip, tax and who pays what: split a bill equally, by shares or by items, rounded up.",
    "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://tipbillsplitcalculator.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Tip, tax and who pays what: split a bill equally, by shares or by items, rounded up.",
        "description": "Enter the bill, the tax rule (included as in most of Europe, or added at the till as in the US) and a tip as a percentage or an amount, before or after tax. Split equally, by shares or by what each person ordered, round each share up to 0.50 or 1, and get an exact who-pays-what table that adds up to the cent.\n\nMethodology:\n- Tax included (VAT): subtotal before tax = bill ÷ (1 + rate); tax = bill − subtotal. Tax added (sales tax): tax = bill × rate, rounded to the cent; bill total = bill + tax.\n- Tip = tip % × tip base, where the base is the subtotal before tax or the total with tax (your choice), rounded to the cent; or a fixed tip amount.\n- Weights: equal = 1 per person; shares = the share you enter; items = each person's ordered amount plus an equal part of anything not assigned to anyone.\n- Bill, tax and tip are each split by weight with the largest-remainder method in whole cents, so the shares add up exactly to the totals.\n- Rounding is applied per person to their exact total; the difference between what is collected and the exact total goes to the tip and is shown separately.",
        "tags": [
          "calculators"
        ],
        "x-mcp-tool": "tip_bill_split_calculator",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TipBillSplitCalculatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Dinner for 4 in Germany, 84.50 incl. VAT, 10% tip, round up to 1",
                  "value": {
                    "symbol": "€",
                    "billAmount": 84.5,
                    "taxMode": "included",
                    "taxPercent": 19,
                    "tipMode": "percent",
                    "tipPercent": 10,
                    "tipBase": "post-tax",
                    "splitMode": "equal",
                    "people": 4,
                    "rounding": "up-1"
                  }
                },
                "example2": {
                  "summary": "US restaurant, 120 + 8.875% sales tax, 20% tip on pre-tax, by items",
                  "value": {
                    "symbol": "$",
                    "billAmount": 120,
                    "taxMode": "added",
                    "taxPercent": 8.875,
                    "tipMode": "percent",
                    "tipPercent": 20,
                    "tipBase": "pre-tax",
                    "splitMode": "items",
                    "persons": [
                      {
                        "name": "Ana",
                        "items": 34
                      },
                      {
                        "name": "Ben",
                        "items": 46
                      },
                      {
                        "name": "Chloe",
                        "items": 28
                      }
                    ],
                    "rounding": "none"
                  }
                },
                "example3": {
                  "summary": "Couple + 2 singles by shares, fixed tip 15",
                  "value": {
                    "symbol": "£",
                    "billAmount": 150,
                    "taxMode": "none",
                    "taxPercent": 0,
                    "tipMode": "amount",
                    "tipAmount": 15,
                    "splitMode": "shares",
                    "persons": [
                      {
                        "name": "Sam & Alex",
                        "shares": 2
                      },
                      {
                        "name": "Jo",
                        "shares": 1
                      },
                      {
                        "name": "Kim",
                        "shares": 1
                      }
                    ],
                    "rounding": "up-0.5"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TipBillSplitCalculatorResult"
                }
              }
            }
          },
          "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"
                }
              }
            }
          }
        }
      },
      "TipBillSplitCalculatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "symbol": {
            "title": "Currency symbol",
            "description": "Display only, e.g. €, $, £, CHF.",
            "type": "string",
            "maxLength": 4,
            "default": "€"
          },
          "billAmount": {
            "title": "Bill amount",
            "description": "The amount printed on the bill (before tip).",
            "type": "number",
            "minimum": 0.01,
            "maximum": 10000000,
            "default": 84.5
          },
          "taxMode": {
            "title": "Tax",
            "type": "string",
            "enum": [
              "included",
              "added",
              "none"
            ],
            "default": "included"
          },
          "taxPercent": {
            "title": "Tax rate",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 19,
            "x-unit": "%"
          },
          "tipMode": {
            "title": "Tip given as",
            "type": "string",
            "enum": [
              "percent",
              "amount"
            ],
            "default": "percent"
          },
          "tipPercent": {
            "title": "Tip percentage",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 10,
            "x-unit": "%"
          },
          "tipAmount": {
            "title": "Tip amount",
            "type": "number",
            "minimum": 0,
            "default": 0
          },
          "tipBase": {
            "title": "Tip calculated on",
            "type": "string",
            "enum": [
              "pre-tax",
              "post-tax"
            ],
            "default": "post-tax"
          },
          "splitMode": {
            "title": "Split",
            "type": "string",
            "enum": [
              "equal",
              "shares",
              "items"
            ],
            "default": "equal"
          },
          "people": {
            "title": "Number of people (equal split)",
            "description": "Used when the list of people below is empty.",
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 4
          },
          "persons": {
            "title": "People",
            "description": "Optional for an equal split. Shares: weight per person (default 1). Items: the bill amount of what each person ordered, in the same terms as the bill (with tax if tax is included); anything not assigned is shared equally.",
            "type": "array",
            "maxItems": 40,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "name": {
                  "title": "Name",
                  "type": "string",
                  "maxLength": 40
                },
                "shares": {
                  "title": "Shares",
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100
                },
                "items": {
                  "title": "Ordered items",
                  "type": "number",
                  "minimum": 0
                }
              },
              "required": [
                "name"
              ]
            }
          },
          "rounding": {
            "title": "Rounding per person",
            "description": "Any rounding difference is added to (or taken from) the tip.",
            "type": "string",
            "enum": [
              "none",
              "up-0.1",
              "up-0.5",
              "up-1",
              "up-5",
              "nearest-0.05"
            ],
            "default": "none"
          }
        },
        "required": [
          "billAmount"
        ]
      },
      "TipBillSplitCalculatorResult": {
        "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",
            "additionalProperties": false,
            "required": [
              "symbol",
              "subtotalBeforeTax",
              "tax",
              "billTotal",
              "tipBase",
              "tip",
              "tipPercentOfBill",
              "grandTotal",
              "collected",
              "roundingAdded",
              "effectiveTip",
              "effectiveTipPercent",
              "people"
            ],
            "properties": {
              "symbol": {
                "type": "string"
              },
              "subtotalBeforeTax": {
                "type": "number"
              },
              "tax": {
                "type": "number"
              },
              "billTotal": {
                "type": "number",
                "description": "Bill including tax, before tip."
              },
              "tipBase": {
                "type": "number",
                "description": "Amount the tip percentage was applied to."
              },
              "tip": {
                "type": "number",
                "description": "Tip before per-person rounding."
              },
              "tipPercentOfBill": {
                "type": "number",
                "description": "Tip as % of the bill including tax."
              },
              "grandTotal": {
                "type": "number",
                "description": "Bill including tax + tip, before rounding."
              },
              "collected": {
                "type": "number",
                "description": "Sum of what everyone pays after rounding."
              },
              "roundingAdded": {
                "type": "number",
                "description": "collected − grandTotal (goes to the tip)."
              },
              "effectiveTip": {
                "type": "number"
              },
              "effectiveTipPercent": {
                "type": "number",
                "description": "Effective tip as % of the tip base."
              },
              "people": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "weight",
                    "billShare",
                    "taxShare",
                    "tipShare",
                    "exact",
                    "pays"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "weight": {
                      "type": "number"
                    },
                    "billShare": {
                      "type": "number"
                    },
                    "taxShare": {
                      "type": "number"
                    },
                    "tipShare": {
                      "type": "number"
                    },
                    "exact": {
                      "type": "number"
                    },
                    "pays": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      }
    }
  }
}