{"openapi":"3.1.0","info":{"title":"myhouse API","version":"1.0.0","description":"Manage shared expenses, shopping lists and projects in your myhouse houses. People and houses go by name; amounts are in the house currency (12.50, not cents). Errors explain what to change."},"servers":[{"url":"https://joinmyhouse.app/v1"}],"components":{"securitySchemes":{"key":{"type":"http","scheme":"bearer","description":"A personal API key from the app: Settings → API access"}}},"security":[{"key":[]}],"paths":{"/me":{"get":{"operationId":"getMe","summary":"Who you are, your houses, and the people in each (use these names elsewhere).","parameters":[],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/balances":{"get":{"operationId":"getBalances","summary":"Who owes whom in a house, and the fewest payments to settle up. Positive = gets money back.","parameters":[{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/payments":{"post":{"operationId":"recordPayment","summary":"Record that someone paid someone back (settles debt).","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["to","amount"],"properties":{"house":{"type":"string","description":"House name or id. Optional if you are in only one house."},"to":{"type":"string","description":"Who was paid (a name)"},"amount":{"type":"number","description":"In the house currency, e.g. 25.50"},"from":{"type":"string","description":"Who paid. Default: you"},"date":{"type":"string","description":"YYYY-MM-DD. Default: today"}}},"example":{"house":"Flat","to":"Rodrigo","amount":25.5}}}},"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/expenses":{"get":{"operationId":"listExpenses","summary":"Recent expenses and payments, newest first.","parameters":[{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."},{"name":"month","in":"query","required":false,"schema":{"type":"string"},"description":"YYYY-MM"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"1–100, default 20"}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}},"post":{"operationId":"addExpense","summary":"Add a shared expense. Split equally between everyone unless you say otherwise.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","amount"],"properties":{"house":{"type":"string","description":"House name or id. Optional if you are in only one house."},"title":{"type":"string","description":"What it was, e.g. \"Groceries\""},"amount":{"type":"number","description":"Total in the house currency, e.g. 42.80"},"paid_by":{"type":"string","description":"Who paid. Default: you"},"split_between":{"type":"array","items":{},"description":"Names to split equally between. Default: everyone"},"shares":{"type":"object","additionalProperties":{"type":"number"},"description":"Exact amounts per person, e.g. {\"Ana\": 30, \"Rui\": 12.80}; must add up to amount"},"date":{"type":"string","description":"YYYY-MM-DD. Default: today"},"category":{"type":"string","description":"groceries, restaurant, home, bills, transport, travel, fun, project or other"}}},"example":{"house":"Flat","title":"Dinner at Taberna","amount":64,"paid_by":"Ana","split_between":["Ana","Rui"],"category":"restaurant"}}}},"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/expenses/{id}":{"patch":{"operationId":"editExpense","summary":"Change an expense (only the fields you send). A new amount re-splits equally unless you send shares.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id from a list call"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"house":{"type":"string","description":"House name or id. Optional if you are in only one house."},"title":{"type":"string","description":""},"amount":{"type":"number","description":""},"paid_by":{"type":"string","description":""},"split_between":{"type":"array","items":{},"description":""},"shares":{"type":"object","additionalProperties":{"type":"number"},"description":""},"date":{"type":"string","description":"YYYY-MM-DD"},"category":{"type":"string","description":""}}}}}},"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}},"delete":{"operationId":"deleteExpense","summary":"Delete an expense or payment.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id from a list call"},{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/lists":{"get":{"operationId":"listLists","summary":"Shopping lists in a house.","parameters":[{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}},"post":{"operationId":"createList","summary":"Create a list, optionally with items.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"house":{"type":"string","description":"House name or id. Optional if you are in only one house."},"title":{"type":"string","description":"e.g. \"Supermarket\""},"items":{"type":"array","items":{},"description":"e.g. [\"milk\", \"eggs\"] or [{\"text\": \"milk\", \"qty\": \"2\"}]"}}}}}},"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/lists/{list}":{"get":{"operationId":"getList","summary":"One list (by name or id) with its items.","parameters":[{"name":"list","in":"path","required":true,"schema":{"type":"string"},"description":"Name or id"},{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/lists/{list}/items":{"post":{"operationId":"addListItems","summary":"Add items to a list (by list name or id). Items already on it are skipped.","parameters":[{"name":"list","in":"path","required":true,"schema":{"type":"string"},"description":"Name or id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"house":{"type":"string","description":"House name or id. Optional if you are in only one house."},"items":{"type":"array","items":{},"description":"e.g. [\"2 milk\", \"eggs\"]"}}},"example":{"house":"Flat","items":["milk","eggs","bananas"]}}}},"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}},"patch":{"operationId":"tickListItems","summary":"Tick items as bought, or untick them, by name.","parameters":[{"name":"list","in":"path","required":true,"schema":{"type":"string"},"description":"Name or id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"house":{"type":"string","description":"House name or id. Optional if you are in only one house."},"got_it":{"type":"array","items":{},"description":"Item names to tick"},"not_yet":{"type":"array","items":{},"description":"Item names to untick"}}}}}},"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/projects":{"get":{"operationId":"listProjects","summary":"Projects (trips, birthdays, DIY) in a house.","parameters":[{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}},"post":{"operationId":"createProject","summary":"Create a project with its to-dos, things to buy and dates in one go.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"house":{"type":"string","description":"House name or id. Optional if you are in only one house."},"title":{"type":"string","description":"e.g. \"Camping in Gerês\""},"start_date":{"type":"string","description":"YYYY-MM-DD"},"end_date":{"type":"string","description":"YYYY-MM-DD"},"location":{"type":"string","description":""},"notes":{"type":"string","description":""},"todos":{"type":"array","items":{},"description":"e.g. [\"Book campsite\"]"},"to_buy":{"type":"array","items":{},"description":"e.g. [{\"text\": \"Tent\", \"price\": 89.99}]"},"dates":{"type":"array","items":{},"description":"e.g. [{\"text\": \"Leave\", \"date\": \"2026-11-20\", \"time\": \"09:00\"}]"}}},"example":{"house":"Flat","title":"Camping in Gerês","start_date":"2026-11-20","end_date":"2026-11-22","todos":["Book campsite"],"to_buy":[{"text":"Gas canister","price":6.5}]}}}},"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/projects/{project}":{"get":{"operationId":"getProject","summary":"One project (by name or id): notes, to-dos, things to buy, dates and what was spent.","parameters":[{"name":"project","in":"path","required":true,"schema":{"type":"string"},"description":"Name or id"},{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/recurring":{"get":{"operationId":"listRecurring","summary":"Recurring bills (rent, internet, subscriptions).","parameters":[{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}},"post":{"operationId":"addRecurring","summary":"Start a recurring bill; each due date adds a normal expense.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","amount","repeat"],"properties":{"house":{"type":"string","description":"House name or id. Optional if you are in only one house."},"title":{"type":"string","description":""},"amount":{"type":"number","description":""},"repeat":{"type":"string","description":"weekly, monthly or yearly"},"start_date":{"type":"string","description":"YYYY-MM-DD. Default: today"},"paid_by":{"type":"string","description":"Default: you"},"split_between":{"type":"array","items":{},"description":"Default: everyone"},"category":{"type":"string","description":"Default: bills"}}}}}},"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}},"/spending":{"get":{"operationId":"getSpending","summary":"A month of spending: total, by category, by person and top places.","parameters":[{"name":"house","in":"query","required":false,"schema":{"type":"string"},"description":"House name or id. Optional if you are in only one house."},{"name":"month","in":"query","required":false,"schema":{"type":"string"},"description":"YYYY-MM. Default: this month"}],"responses":{"200":{"description":"OK (JSON)"},"400":{"description":"Something to fix; \"error\" says what"},"401":{"description":"Missing or bad API key"},"403":{"description":"Read-only key, or API access off for that house"}}}}}}