{
  "openapi": "3.1.0",
  "info": {
    "title": "Meet by OpenApps",
    "version": "1.0.0",
    "summary": "Make free video call links with no time limit.",
    "description": "Meet is a free video call app with no time limit and no sign-up. This API makes meeting links an assistant can put in a calendar invite or message. No key and no account; CORS is open. Calls happen in the browser at https://meet-free.openapps.xyz/, peer to peer, and work best for up to about 6 people. Errors are JSON with an `error` sentence that says what to change.",
    "contact": { "name": "OpenApps", "url": "https://free-apps.openapps.xyz/" },
    "license": { "name": "Free to use" }
  },
  "externalDocs": { "description": "Guide for assistants", "url": "https://meet-free.openapps.xyz/llms.txt" },
  "servers": [{ "url": "https://functions.bounded.sh/apps/a4b391bf10db92e58e21517e/api" }],
  "paths": {
    "/": {
      "get": {
        "operationId": "listRoutes",
        "summary": "List the API's routes",
        "responses": {
          "200": {
            "description": "The routes and where the docs are.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": { "type": "string" },
                    "about": { "type": "string" },
                    "docs": { "type": "string", "format": "uri" },
                    "openapi": { "type": "string", "format": "uri" },
                    "routes": { "type": "array", "items": { "type": "string" } }
                  }
                },
                "example": {
                  "name": "Meet by OpenApps",
                  "about": "Free video calls with no time limit and no sign-up. This API makes meeting links; the call itself happens in the browser.",
                  "docs": "https://meet-free.openapps.xyz/llms.txt",
                  "openapi": "https://meet-free.openapps.xyz/openapi.json",
                  "routes": ["POST /rooms {title?, waitingRoom?} -> a meeting link anyone can join, and a host link for the person who runs the meeting"]
                }
              }
            }
          }
        }
      }
    },
    "/rooms": {
      "post": {
        "operationId": "createRoom",
        "summary": "Make a meeting link",
        "description": "Creates a meeting room and returns its link (for everyone) and its host link (for the organizer only). The link never expires and has no time limit, so it can be reused for a recurring meeting. The body is optional.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/RoomInput" },
              "examples": {
                "simple": { "value": { "title": "Weekly sync" } },
                "waitingRoom": { "value": { "title": "Interview with Sam", "waitingRoom": true } }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The meeting link was made.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Room" },
                "example": {
                  "id": "Xk3pQ8rT2mWv9aLs4dHy",
                  "title": "Weekly sync",
                  "url": "https://meet-free.openapps.xyz/r/Xk3pQ8rT2mWv9aLs4dHy",
                  "hostUrl": "https://meet-free.openapps.xyz/r/Xk3pQ8rT2mWv9aLs4dHy#k=Hq7Zr2mXc9Lp4Tn8Wb3Ks6Vd",
                  "waitingRoom": false,
                  "invite": "Weekly sync\nJoin the video call: https://meet-free.openapps.xyz/r/Xk3pQ8rT2mWv9aLs4dHy\nNo account or app needed. Open the link in a browser on a phone or computer.",
                  "notes": [
                    "Put url in the calendar invite or message. Anyone with it can join; there is no time limit.",
                    "Give hostUrl only to the person running the meeting. Opening it makes them a host: they can let people in from the waiting room, lock the meeting and remove people.",
                    "The link keeps working, so it can be reused for a recurring meeting."
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body could not be used.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "example": { "error": "title can be up to 80 characters." }
              }
            }
          },
          "500": {
            "description": "The link could not be made right now.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "example": { "error": "Could not make a meeting link: try again in a moment." }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "RoomInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "title": { "type": "string", "maxLength": 80, "description": "A name for the meeting, shown in the call and in the invitation text." },
          "waitingRoom": { "type": "boolean", "default": false, "description": "When true, people wait until a host lets them in." }
        }
      },
      "Room": {
        "type": "object",
        "required": ["id", "title", "url", "hostUrl", "waitingRoom", "invite", "notes"],
        "properties": {
          "id": { "type": "string", "pattern": "^[A-Za-z0-9]{20}$", "description": "The room id." },
          "title": { "type": "string" },
          "url": { "type": "string", "format": "uri", "description": "The meeting link. Anyone with it can join from a browser, with no account." },
          "hostUrl": { "type": "string", "format": "uri", "description": "The host link, for the organizer only. Opening it makes that browser a host: it can let people in, lock the meeting and remove people." },
          "waitingRoom": { "type": "boolean" },
          "invite": { "type": "string", "description": "Ready invitation text with the link." },
          "notes": { "type": "array", "items": { "type": "string" } }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": { "error": { "type": "string", "description": "What went wrong and what to change." } }
      }
    }
  }
}
