{
  "openapi": "3.1.0",
  "info": {
    "title": "Lists API",
    "version": "1.0.0",
    "summary": "Free shared grocery and to-do lists that update live for everyone in the house.",
    "description": "Make shared lists, add items, check them off and read them back. Making a list needs no key; everything else needs the list key in the x-list-key header (returned when a list is made, or copied from the list's Share screen in the app). The key works like the share link: anyone with it can read and change the list. Errors are JSON with an error sentence that says what to change. Free with no limits. Full guide: https://lists-free.openapps.xyz/llms.txt",
    "contact": {
      "name": "OpenApps",
      "url": "https://free-apps.openapps.xyz/"
    }
  },
  "servers": [
    {
      "url": "https://functions.bounded.sh/apps/ee59501e91bae6d2c23a8370/api"
    }
  ],
  "externalDocs": {
    "description": "llms.txt",
    "url": "https://lists-free.openapps.xyz/llms.txt"
  },
  "paths": {
    "/": {
      "get": {
        "operationId": "describe",
        "summary": "Describe the API and its routes",
        "responses": {
          "200": {
            "description": "Name, docs link and routes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "about": {
                      "type": "string"
                    },
                    "docs": {
                      "type": "string"
                    },
                    "openapi": {
                      "type": "string"
                    },
                    "routes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/lists": {
      "post": {
        "operationId": "createList",
        "summary": "Make a new shared list (no key needed)",
        "description": "Returns the list key for later calls, a share link for the household and an admin link for the owner.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateList"
              },
              "example": {
                "name": "Groceries",
                "items": [
                  "milk and eggs",
                  "2 lb chicken"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ListSummary"
                    },
                    {
                      "type": "object",
                      "required": [
                        "key",
                        "shareUrl",
                        "adminUrl"
                      ],
                      "properties": {
                        "key": {
                          "type": "string",
                          "description": "The list key (44 letters and digits). Send it as x-list-key."
                        },
                        "shareUrl": {
                          "type": "string",
                          "format": "uri",
                          "description": "Give this to the person; anyone who opens it is on the list."
                        },
                        "adminUrl": {
                          "type": "string",
                          "format": "uri",
                          "description": "Only for the list's owner: remove people, change the link, delete the list."
                        },
                        "next": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "list": {
                    "id": "PG2nGY8htowKaWGc7qmv",
                    "name": "Groceries",
                    "kind": "grocery",
                    "url": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv"
                  },
                  "toGet": [
                    {
                      "id": "i0rkl7un1d1x3ht",
                      "name": "Chicken",
                      "quantity": "2 lb",
                      "note": null,
                      "section": "meat",
                      "sectionName": "Meat and seafood",
                      "checked": false
                    },
                    {
                      "id": "i0otvjk61s1cktm",
                      "name": "Eggs",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    },
                    {
                      "id": "i11w0wwy0lp762e",
                      "name": "Milk",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    }
                  ],
                  "checkedOff": [],
                  "say": "Groceries has 3 items to get: 2 lb chicken, Eggs, Milk.",
                  "key": "PG2nGY8htowKaWGc7qmvDSecAULzKfzLCZCo3urSrNuK",
                  "shareUrl": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv#DSecAULzKfzLCZCo3urSrNuK",
                  "adminUrl": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv/admin#nfY3cduM4nKoDpd6VEpwBQZf"
                }
              }
            }
          },
          "400": {
            "description": "Bad name, kind or items",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/list": {
      "get": {
        "security": [
          {
            "listKey": []
          }
        ],
        "operationId": "readList",
        "summary": "Read a list: what to get in store order, what is checked off, and a sentence to read out",
        "responses": {
          "200": {
            "description": "The list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListSummary"
                },
                "example": {
                  "list": {
                    "id": "PG2nGY8htowKaWGc7qmv",
                    "name": "Groceries",
                    "kind": "grocery",
                    "url": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv"
                  },
                  "toGet": [
                    {
                      "id": "i0rkl7un1d1x3ht",
                      "name": "Chicken",
                      "quantity": "2 lb",
                      "note": null,
                      "section": "meat",
                      "sectionName": "Meat and seafood",
                      "checked": false
                    },
                    {
                      "id": "i0otvjk61s1cktm",
                      "name": "Eggs",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    },
                    {
                      "id": "i11w0wwy0lp762e",
                      "name": "Milk",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    }
                  ],
                  "checkedOff": [],
                  "say": "Groceries has 3 items to get: 2 lb chicken, Eggs, Milk."
                }
              }
            }
          },
          "401": {
            "description": "No list key, or not 44 letters and digits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key does not work; the link may have been changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "The list was deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/list/items": {
      "post": {
        "security": [
          {
            "listKey": []
          }
        ],
        "operationId": "addItems",
        "summary": "Add items, from text (\"milk and eggs\") or a list",
        "description": "Items already on the list are not added twice; checked-off items come back unchecked. A leading amount becomes the quantity (\"2 lb chicken\"). Up to 50 items per call.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddItems"
              },
              "examples": {
                "text": {
                  "value": {
                    "text": "milk and eggs, 2 lb chicken"
                  }
                },
                "items": {
                  "value": {
                    "items": [
                      "milk",
                      {
                        "name": "coffee",
                        "quantity": "1 bag",
                        "note": "decaf",
                        "section": "drinks"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nothing new: everything was already on the list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ListSummary"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "added": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Item"
                          }
                        },
                        "alreadyOnList": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "list": {
                    "id": "PG2nGY8htowKaWGc7qmv",
                    "name": "Groceries",
                    "kind": "grocery",
                    "url": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv"
                  },
                  "toGet": [
                    {
                      "id": "i0rkl7un1d1x3ht",
                      "name": "Chicken",
                      "quantity": "2 lb",
                      "note": null,
                      "section": "meat",
                      "sectionName": "Meat and seafood",
                      "checked": false
                    },
                    {
                      "id": "i0otvjk61s1cktm",
                      "name": "Eggs",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    },
                    {
                      "id": "i11w0wwy0lp762e",
                      "name": "Milk",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    }
                  ],
                  "checkedOff": [],
                  "say": "Groceries has 3 items to get: 2 lb chicken, Eggs, Milk."
                }
              }
            }
          },
          "201": {
            "description": "Items added",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ListSummary"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "added": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Item"
                          }
                        },
                        "alreadyOnList": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "list": {
                    "id": "PG2nGY8htowKaWGc7qmv",
                    "name": "Groceries",
                    "kind": "grocery",
                    "url": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv"
                  },
                  "toGet": [
                    {
                      "id": "i0rkl7un1d1x3ht",
                      "name": "Chicken",
                      "quantity": "2 lb",
                      "note": null,
                      "section": "meat",
                      "sectionName": "Meat and seafood",
                      "checked": false
                    },
                    {
                      "id": "i0otvjk61s1cktm",
                      "name": "Eggs",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    },
                    {
                      "id": "i11w0wwy0lp762e",
                      "name": "Milk",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    }
                  ],
                  "checkedOff": [],
                  "say": "Groceries has 3 items to get: 2 lb chicken, Eggs, Milk."
                }
              }
            }
          },
          "400": {
            "description": "Nothing to add, too many items, or a bad section",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No list key, or not 44 letters and digits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key does not work; the link may have been changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "The list was deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/list/items/{item}": {
      "parameters": [
        {
          "name": "item",
          "in": "path",
          "required": true,
          "description": "The item's id, or its name (URL-encoded), like milk or olive%20oil",
          "schema": {
            "type": "string"
          },
          "example": "milk"
        }
      ],
      "patch": {
        "security": [
          {
            "listKey": []
          }
        ],
        "operationId": "updateItem",
        "summary": "Check off, uncheck, rename or change an item",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchItem"
              },
              "example": {
                "checked": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The list after the change",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ListSummary"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "updated": {
                          "$ref": "#/components/schemas/Item"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "list": {
                    "id": "PG2nGY8htowKaWGc7qmv",
                    "name": "Groceries",
                    "kind": "grocery",
                    "url": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv"
                  },
                  "toGet": [
                    {
                      "id": "i0rkl7un1d1x3ht",
                      "name": "Chicken",
                      "quantity": "2 lb",
                      "note": null,
                      "section": "meat",
                      "sectionName": "Meat and seafood",
                      "checked": false
                    },
                    {
                      "id": "i0otvjk61s1cktm",
                      "name": "Eggs",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    },
                    {
                      "id": "i11w0wwy0lp762e",
                      "name": "Milk",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    }
                  ],
                  "checkedOff": [],
                  "say": "Groceries has 3 items to get: 2 lb chicken, Eggs, Milk."
                }
              }
            }
          },
          "400": {
            "description": "Nothing to change, a bad value, or an item path that is not URL-encoded correctly",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No list key, or not 44 letters and digits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key does not work; the link may have been changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "That item is not on the list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Renaming onto an item already on the list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "The list was deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "security": [
          {
            "listKey": []
          }
        ],
        "operationId": "removeItem",
        "summary": "Remove an item from the list",
        "responses": {
          "200": {
            "description": "The list after removing the item",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ListSummary"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "removed": {
                          "$ref": "#/components/schemas/Item"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "list": {
                    "id": "PG2nGY8htowKaWGc7qmv",
                    "name": "Groceries",
                    "kind": "grocery",
                    "url": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv"
                  },
                  "toGet": [
                    {
                      "id": "i0rkl7un1d1x3ht",
                      "name": "Chicken",
                      "quantity": "2 lb",
                      "note": null,
                      "section": "meat",
                      "sectionName": "Meat and seafood",
                      "checked": false
                    },
                    {
                      "id": "i0otvjk61s1cktm",
                      "name": "Eggs",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    },
                    {
                      "id": "i11w0wwy0lp762e",
                      "name": "Milk",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    }
                  ],
                  "checkedOff": [],
                  "say": "Groceries has 3 items to get: 2 lb chicken, Eggs, Milk."
                }
              }
            }
          },
          "400": {
            "description": "The item in the path is not URL-encoded correctly",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No list key, or not 44 letters and digits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key does not work; the link may have been changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "That item is not on the list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "The list was deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/list/clear-checked": {
      "post": {
        "security": [
          {
            "listKey": []
          }
        ],
        "operationId": "clearChecked",
        "summary": "Remove everything checked off",
        "responses": {
          "200": {
            "description": "The list after clearing",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ListSummary"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "removed": {
                          "type": "integer"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "list": {
                    "id": "PG2nGY8htowKaWGc7qmv",
                    "name": "Groceries",
                    "kind": "grocery",
                    "url": "https://lists-free.openapps.xyz/l/PG2nGY8htowKaWGc7qmv"
                  },
                  "toGet": [
                    {
                      "id": "i0rkl7un1d1x3ht",
                      "name": "Chicken",
                      "quantity": "2 lb",
                      "note": null,
                      "section": "meat",
                      "sectionName": "Meat and seafood",
                      "checked": false
                    },
                    {
                      "id": "i0otvjk61s1cktm",
                      "name": "Eggs",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    },
                    {
                      "id": "i11w0wwy0lp762e",
                      "name": "Milk",
                      "quantity": null,
                      "note": null,
                      "section": "dairy",
                      "sectionName": "Dairy and eggs",
                      "checked": false
                    }
                  ],
                  "checkedOff": [],
                  "say": "Groceries has 3 items to get: 2 lb chicken, Eggs, Milk."
                }
              }
            }
          },
          "401": {
            "description": "No list key, or not 44 letters and digits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key does not work; the link may have been changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "The list was deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "listKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-list-key",
        "description": "The list key: 44 letters and digits, from POST /lists or the list's Share screen."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "A sentence that says what to change."
          }
        },
        "example": {
          "error": "Send the list key in the x-list-key header."
        }
      },
      "Section": {
        "type": "string",
        "enum": [
          "produce",
          "bakery",
          "deli",
          "meat",
          "dairy",
          "frozen",
          "pantry",
          "baking",
          "breakfast",
          "snacks",
          "drinks",
          "household",
          "personal",
          "baby",
          "pets",
          "other"
        ]
      },
      "Item": {
        "type": "object",
        "required": [
          "id",
          "name",
          "section",
          "checked"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "section": {
            "$ref": "#/components/schemas/Section"
          },
          "sectionName": {
            "type": "string"
          },
          "checked": {
            "type": "boolean"
          }
        },
        "example": {
          "id": "i11w0wwy0lp762e",
          "name": "Milk",
          "quantity": null,
          "note": null,
          "section": "dairy",
          "sectionName": "Dairy and eggs",
          "checked": false
        }
      },
      "ListSummary": {
        "type": "object",
        "required": [
          "list",
          "toGet",
          "checkedOff",
          "say"
        ],
        "properties": {
          "list": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "kind": {
                "type": "string",
                "enum": [
                  "grocery",
                  "todo"
                ]
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "toGet": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Item"
            },
            "description": "Unchecked items, in store order (grocery) or the order added (todo)."
          },
          "checkedOff": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "say": {
            "type": "string",
            "description": "One sentence to read out."
          }
        }
      },
      "NewItem": {
        "oneOf": [
          {
            "type": "string",
            "description": "Like \"2 lb chicken\" or \"milk and eggs\"."
          },
          {
            "type": "object",
            "required": [
              "name"
            ],
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 100
              },
              "quantity": {
                "type": "string",
                "maxLength": 40
              },
              "note": {
                "type": "string",
                "maxLength": 300
              },
              "section": {
                "$ref": "#/components/schemas/Section"
              }
            }
          }
        ]
      },
      "CreateList": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 60,
            "default": "Groceries"
          },
          "kind": {
            "type": "string",
            "enum": [
              "grocery",
              "todo"
            ]
          },
          "items": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/NewItem"
            }
          },
          "text": {
            "type": "string"
          }
        }
      },
      "AddItems": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "Split on commas, new lines and \"and\"."
          },
          "items": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/NewItem"
            }
          }
        }
      },
      "PatchItem": {
        "type": "object",
        "properties": {
          "checked": {
            "type": "boolean"
          },
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "quantity": {
            "type": "string",
            "maxLength": 40
          },
          "note": {
            "type": "string",
            "maxLength": 300
          },
          "section": {
            "$ref": "#/components/schemas/Section"
          }
        }
      }
    }
  }
}