{
  "openapi": "3.1.0",
  "info": {
    "title": "Mystro website preview API",
    "version": "0.1.0-preview",
    "description": "Local preview website intake only. This is not the Mystro agent API and does not grant credentials or confirm product availability. A receipt confirms only durable local storage. Production storage and deployment are pending. Public metrics expose aggregate counts only; collection uses a private durable local ledger fed by read-only VPS aggregation."
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "paths": {
    "/api/developer-access": {
      "post": {
        "operationId": "requestDeveloperAccess",
        "summary": "Record a developer-access request",
        "description": "JSON body at most 16384 bytes. Text fields email, companyWebsite, workflow and timing are trimmed before validation and idempotency comparison. The idempotency key must be a canonical hyphenated UUID. Use the same key and body when retrying. Browser requests require same-origin Origin; no CORS permission is granted. Local preview rate limit is 30 requests per client address per minute; loopback proxy clients share a bucket. No authentication or outbound email is involved.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeveloperAccessRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Durably committed new request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "200": {
            "description": "Replay of the same normalized request and idempotency key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON or invalid request fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Origin does not match the request origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency key was previously used with different content.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 16384 bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type must be application/json.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Local preview rate limit exceeded; retry after one minute.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Storage unavailable; no receipt has been confirmed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/metrics": {
      "get": {
        "operationId": "getPublicMetrics",
        "summary": "Read the latest aggregate usage snapshot",
        "description": "No authentication. Snapshot refreshes every 120 seconds when the collector is enabled. Responses are cached for 60 seconds. No transcript scans occur in this request. On collection failure the last snapshot remains available with its original updatedAt; before the first snapshot return 503. Counts deduplicate message IDs using maximum observed input, output, cache-creation input and cache-read input token sum; session IDs are counted distinctly. Durable ledger prevents decreases after transcript deletion, starting with retained history at first collection, not complete lifetime usage.",
        "responses": {
          "200": {
            "description": "Latest successfully committed aggregate snapshot.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "public, max-age=60"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicMetrics"
                }
              }
            }
          },
          "503": {
            "description": "No usable metrics snapshot is available. Cache-Control: no-store.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "const": "metrics_unavailable"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "DeveloperAccessRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "email",
          "companyWebsite",
          "role",
          "workflow",
          "idempotencyKey"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "companyWebsite": {
            "type": "string",
            "format": "uri",
            "pattern": "^https?://",
            "maxLength": 2048
          },
          "role": {
            "type": "string",
            "enum": [
              "founder",
              "engineer",
              "agency",
              "other"
            ]
          },
          "workflow": {
            "type": "string",
            "minLength": 20,
            "maxLength": 4000
          },
          "timing": {
            "type": "string",
            "maxLength": 120
          },
          "idempotencyKey": {
            "type": "string",
            "format": "uuid"
          },
          "attribution": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "utm_source": {
                "type": "string",
                "maxLength": 200
              },
              "utm_medium": {
                "type": "string",
                "maxLength": 200
              },
              "utm_campaign": {
                "type": "string",
                "maxLength": 200
              },
              "utm_content": {
                "type": "string",
                "maxLength": 200
              },
              "utm_term": {
                "type": "string",
                "maxLength": 200
              },
              "gclid": {
                "type": "string",
                "maxLength": 200
              },
              "fbclid": {
                "type": "string",
                "maxLength": 200
              }
            }
          }
        }
      },
      "Receipt": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "requestId",
          "receivedAt",
          "status"
        ],
        "properties": {
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "const": "received"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "PublicMetrics": {
        "type": "object",
        "required": [
          "tokensProcessed",
          "agentSessions",
          "updatedAt"
        ],
        "additionalProperties": false,
        "properties": {
          "tokensProcessed": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "agentSessions": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "example": {
          "tokensProcessed": 1420250141,
          "agentSessions": 1239,
          "updatedAt": "2026-09-09T08:00:00Z"
        }
      }
    }
  }
}
