{
  "openapi": "3.1.0",
  "info": {
    "title": "Pay Pong read-only group status API",
    "version": "1.0.0",
    "description": "Read the current payer rotation for one Pay Pong group when its owner has shared a revocable private live link. This API cannot create groups, log turns, view receipts or amounts, or move money."
  },
  "servers": [
    { "url": "https://paypong.app/api/muse/v1" }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "getPayPongConnectorInfo",
        "summary": "Get API information",
        "description": "Returns the documentation and OpenAPI URLs for this read-only API.",
        "responses": {
          "200": {
            "description": "API information",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiInfo" }
              }
            }
          }
        }
      }
    },
    "/next-payer": {
      "post": {
        "operationId": "getNextPayerFromPrivateLink",
        "summary": "Find who pays next for a shared group",
        "description": "Use only a private live link supplied by the user or the group owner. The link grants read-only access to limited turn status and can be revoked by the owner. Do not put a live link in a public prompt, URL parameter, or log.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/NextPayerRequest" },
              "examples": {
                "privateLink": {
                  "summary": "Example format with a nonworking token",
                  "value": {
                    "shareUrl": "https://paypong.app/share/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Limited group turn status",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/GroupStatus" }
              }
            }
          },
          "400": {
            "description": "The link format is invalid",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } }
          },
          "404": {
            "description": "The link was revoked or the group is unavailable",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } }
          },
          "409": {
            "description": "The group does not have a complete rotation yet",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } }
          },
          "500": {
            "description": "The group status could not be loaded",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiInfo": {
        "type": "object",
        "required": ["name", "version", "documentationUrl", "openApiUrl"],
        "properties": {
          "name": { "type": "string" },
          "version": { "type": "string" },
          "documentationUrl": { "type": "string", "format": "uri" },
          "openApiUrl": { "type": "string", "format": "uri" }
        },
        "additionalProperties": false
      },
      "NextPayerRequest": {
        "type": "object",
        "required": ["shareUrl"],
        "properties": {
          "shareUrl": {
            "type": "string",
            "format": "uri",
            "description": "A private live link copied from a Pay Pong group. Treat it as a secret because anyone holding it can read that group's limited status."
          }
        },
        "additionalProperties": false
      },
      "GroupStatus": {
        "type": "object",
        "required": ["groupName", "nextPayerName", "lastPayerName", "participantNames", "turnCount", "updatedAt"],
        "properties": {
          "groupName": { "type": "string" },
          "nextPayerName": { "type": "string", "description": "First name of the person suggested to pay next." },
          "lastPayerName": { "type": ["string", "null"], "description": "First name of the last payer, or null if no turns are logged." },
          "participantNames": { "type": "array", "items": { "type": "string" } },
          "turnCount": { "type": "integer", "minimum": 0 },
          "updatedAt": { "type": "string", "format": "date-time" }
        },
        "additionalProperties": false
      },
      "ApiError": {
        "type": "object",
        "required": ["error"],
        "properties": { "error": { "type": "string" } },
        "additionalProperties": false
      }
    }
  }
}
