From cc5d71d39f192547cc6618f55eb6e7f35e4af0d8 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Tue, 1 Sep 2026 13:09:40 -0700 Subject: [PATCH] Generate OpenAPI from App Router handlers with inferred contracts and source analysis --- public/openapi.json | 20853 ++++++++++++++++++++++++++++++- scripts/check-openapi.ts | 14 +- scripts/generate-openapi.ts | 2 +- src/openapi/README.md | 25 +- src/openapi/contracts.ts | 2 +- src/openapi/coverage.ts | 38 +- src/openapi/discover.ts | 9 +- src/openapi/document.ts | 11 +- src/openapi/infer.ts | 227 + src/openapi/operation.ts | 1 + src/openapi/source-analysis.ts | 744 ++ 11 files changed, 21892 insertions(+), 34 deletions(-) create mode 100644 src/openapi/infer.ts create mode 100644 src/openapi/source-analysis.ts diff --git a/public/openapi.json b/public/openapi.json index 39f010443..2d043c653 100644 --- a/public/openapi.json +++ b/public/openapi.json @@ -18,6 +18,57 @@ }, "description": "Bad request." }, + "ForbiddenResponse": { + "content": { + "application/json": { + "example": { + "error": { + "code": "forbidden", + "message": "Forbidden.", + "status": 403 + } + }, + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + }, + "description": "Forbidden." + }, + "NotFoundResponse": { + "content": { + "application/json": { + "example": { + "error": { + "code": "not-found", + "message": "Not found.", + "status": 404 + } + }, + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + }, + "description": "Not found." + }, + "PayloadTooLargeResponse": { + "content": { + "application/json": { + "example": { + "error": { + "code": "payload-too-large", + "message": "Payload too large.", + "status": 413 + } + }, + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + }, + "description": "Payload too large." + }, "ServerErrorResponse": { "content": { "application/json": { @@ -642,7 +693,7 @@ "url": "https://docs.umami.is/docs/api" }, "info": { - "description": "REST API for Umami analytics. Self-hosted deployments serve these paths beneath their configured BASE_PATH.", + "description": "REST API for Umami analytics. Every App Router API operation is included. Operations marked with x-umami-contract: inferred are generated from handler source; colocated explicit contracts provide curated descriptions and exact response models. Self-hosted deployments serve these paths beneath their configured BASE_PATH.", "license": { "identifier": "MIT", "name": "MIT" @@ -652,6 +703,897 @@ }, "openapi": "3.1.0", "paths": { + "/api/2fa/disable": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPost2faDisable", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "password": { + "type": "string" + }, + "token": { + "maxLength": 6, + "minLength": 6, + "type": "string" + } + }, + "required": [ + "password", + "token" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "403": { + "$ref": "#/components/responses/ForbiddenResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + }, + "429": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailableResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update 2fa disable", + "tags": [ + "Two-factor authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/2fa/disable/route.ts" + } + }, + "/api/2fa/setup/cancel": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPost2faSetupCancel", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update 2fa setup cancel", + "tags": [ + "Two-factor authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/2fa/setup/cancel/route.ts" + } + }, + "/api/2fa/setup/confirm": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPost2faSetupConfirm", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "token": { + "maxLength": 6, + "minLength": 6, + "type": "string" + } + }, + "required": [ + "token" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + }, + "429": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailableResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update 2fa setup confirm", + "tags": [ + "Two-factor authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/2fa/setup/confirm/route.ts" + } + }, + "/api/2fa/setup/initiate": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPost2faSetupInitiate", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailableResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update 2fa setup initiate", + "tags": [ + "Two-factor authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/2fa/setup/initiate/route.ts" + } + }, + "/api/2fa/status": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGet2faStatus", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get 2fa status", + "tags": [ + "Two-factor authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/2fa/status/route.ts" + } + }, + "/api/2fa/verify": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPost2faVerify", + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "properties": { + "token": { + "maxLength": 6, + "minLength": 6, + "type": "string" + } + }, + "required": [ + "token" + ], + "type": "object" + }, + { + "properties": { + "backupCode": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "backupCode" + ], + "type": "object" + } + ] + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + }, + "429": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailableResponse" + } + }, + "security": [], + "summary": "Create or update 2fa verify", + "tags": [ + "Two-factor authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/2fa/verify/route.ts" + } + }, + "/api/admin/2fa/global": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostAdmin2faGlobal", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "required": { + "type": "boolean" + } + }, + "required": [ + "required" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailableResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update admin 2fa global", + "tags": [ + "Administration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/admin/2fa/global/route.ts" + } + }, + "/api/admin/teams": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetAdminTeams", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get admin teams", + "tags": [ + "Administration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/admin/teams/route.ts" + } + }, + "/api/admin/teams/{teamId}/2fa": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostAdminTeamsTeamId2fa", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "required": { + "type": "boolean" + } + }, + "required": [ + "required" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailableResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update admin teams team id 2fa", + "tags": [ + "Administration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/admin/teams/[teamId]/2fa/route.ts" + } + }, + "/api/admin/users": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetAdminUsers", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get admin users", + "tags": [ + "Administration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/admin/users/route.ts" + } + }, + "/api/admin/users/{userId}/2fa": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteAdminUsersUserId2fa", + "parameters": [ + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete admin users user id 2fa", + "tags": [ + "Administration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/admin/users/[userId]/2fa/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetAdminUsersUserId2fa", + "parameters": [ + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get admin users user id 2fa", + "tags": [ + "Administration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/admin/users/[userId]/2fa/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostAdminUsersUserId2fa", + "parameters": [ + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "required": { + "type": "boolean" + } + }, + "required": [ + "required" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailableResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update admin users user id 2fa", + "tags": [ + "Administration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/admin/users/[userId]/2fa/route.ts" + } + }, + "/api/admin/websites": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetAdminWebsites", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get admin websites", + "tags": [ + "Administration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/admin/websites/route.ts" + } + }, "/api/auth/login": { "post": { "description": "Authenticates a self-hosted Umami user. Users with two-factor authentication receive a short-lived partial token instead of a full bearer token.", @@ -692,7 +1634,6331 @@ "tags": [ "Authentication" ], - "x-umami-audience": "public" + "x-umami-audience": "public", + "x-umami-contract": "explicit", + "x-umami-source": "src/app/api/auth/login/contract.ts" + } + }, + "/api/auth/logout": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostAuthLogout", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update auth logout", + "tags": [ + "Authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/auth/logout/route.ts" + } + }, + "/api/auth/sso": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostAuthSso", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "500": { + "$ref": "#/components/responses/ServerErrorResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update auth sso", + "tags": [ + "Authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/auth/sso/route.ts" + } + }, + "/api/auth/subscription": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetAuthSubscription", + "parameters": [ + { + "in": "query", + "name": "teamId", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get auth subscription", + "tags": [ + "Authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/auth/subscription/route.ts" + } + }, + "/api/auth/verify": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostAuthVerify", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update auth verify", + "tags": [ + "Authentication" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/auth/verify/route.ts" + } + }, + "/api/batch": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostBatch", + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "maxItems": 500, + "type": "array" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "500": { + "$ref": "#/components/responses/ServerErrorResponse" + } + }, + "security": [], + "summary": "Create or update batch", + "tags": [ + "Collection" + ], + "x-umami-audience": "collect", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/batch/route.ts" + } + }, + "/api/boards": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetBoards", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get boards", + "tags": [ + "Boards" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/boards/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostBoards", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "description": { + "maxLength": 500, + "type": "string" + }, + "name": { + "maxLength": 100, + "type": "string" + }, + "parameters": { + "properties": { + "linkId": { + "format": "uuid", + "type": "string" + }, + "pixelId": { + "format": "uuid", + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "type": "object" + }, + "teamId": { + "anyOf": [ + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "type": { + "anyOf": [ + { + "enum": [], + "type": "string" + }, + { + "const": "open" + } + ] + }, + "userId": { + "anyOf": [ + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "type", + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update boards", + "tags": [ + "Boards" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/boards/route.ts" + } + }, + "/api/boards/{boardId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteBoardsBoardId", + "parameters": [ + { + "in": "path", + "name": "boardId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete boards board id", + "tags": [ + "Boards" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/boards/[boardId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetBoardsBoardId", + "parameters": [ + { + "in": "path", + "name": "boardId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get boards board id", + "tags": [ + "Boards" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/boards/[boardId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostBoardsBoardId", + "parameters": [ + { + "in": "path", + "name": "boardId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "description": { + "maxLength": 500, + "type": "string" + }, + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "properties": {}, + "type": "object" + }, + "type": { + "anyOf": [ + { + "enum": [], + "type": "string" + }, + { + "const": "open" + } + ] + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "500": { + "$ref": "#/components/responses/ServerErrorResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update boards board id", + "tags": [ + "Boards" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/boards/[boardId]/route.ts" + } + }, + "/api/boards/{boardId}/clone": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostBoardsBoardIdClone", + "parameters": [ + { + "in": "path", + "name": "boardId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "description": { + "maxLength": 500, + "type": "string" + }, + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "properties": {}, + "type": "object" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update boards board id clone", + "tags": [ + "Boards" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/boards/[boardId]/clone/route.ts" + } + }, + "/api/boards/{boardId}/shares": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetBoardsBoardIdShares", + "parameters": [ + { + "in": "path", + "name": "boardId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get boards board id shares", + "tags": [ + "Boards" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/boards/[boardId]/shares/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostBoardsBoardIdShares", + "parameters": [ + { + "in": "path", + "name": "boardId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update boards board id shares", + "tags": [ + "Boards" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/boards/[boardId]/shares/route.ts" + } + }, + "/api/config": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetConfig", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + } + }, + "security": [], + "summary": "Get config", + "tags": [ + "Configuration" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/config/route.ts" + } + }, + "/api/dashboard": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetDashboard", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get dashboard", + "tags": [ + "Dashboard" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/dashboard/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostDashboard", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "description": { + "maxLength": 500, + "type": "string" + }, + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "properties": {}, + "type": "object" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update dashboard", + "tags": [ + "Dashboard" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/dashboard/route.ts" + } + }, + "/api/heartbeat": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetHeartbeat", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + } + }, + "security": [], + "summary": "Get heartbeat", + "tags": [ + "System" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/heartbeat/route.ts" + } + }, + "/api/links": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetLinks", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get links", + "tags": [ + "Links" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/links/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostLinks", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "anyOf": [ + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "name": { + "maxLength": 100, + "type": "string" + }, + "slug": { + "maxLength": 100, + "minLength": 8, + "type": "string" + }, + "teamId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "url": { + "maxLength": 500, + "type": "string" + } + }, + "required": [ + "name", + "url", + "slug" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update links", + "tags": [ + "Links" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/links/route.ts" + } + }, + "/api/links/{linkId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteLinksLinkId", + "parameters": [ + { + "in": "path", + "name": "linkId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete links link id", + "tags": [ + "Links" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/links/[linkId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetLinksLinkId", + "parameters": [ + { + "in": "path", + "name": "linkId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get links link id", + "tags": [ + "Links" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/links/[linkId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostLinksLinkId", + "parameters": [ + { + "in": "path", + "name": "linkId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "slug": { + "maxLength": 100, + "minLength": 8, + "type": "string" + }, + "url": { + "maxLength": 500, + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "500": { + "$ref": "#/components/responses/ServerErrorResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update links link id", + "tags": [ + "Links" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/links/[linkId]/route.ts" + } + }, + "/api/links/{linkId}/shares": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetLinksLinkIdShares", + "parameters": [ + { + "in": "path", + "name": "linkId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get links link id shares", + "tags": [ + "Links" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/links/[linkId]/shares/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostLinksLinkIdShares", + "parameters": [ + { + "in": "path", + "name": "linkId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update links link id shares", + "tags": [ + "Links" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/links/[linkId]/shares/route.ts" + } + }, + "/api/links/charts": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetLinksCharts", + "parameters": [ + { + "in": "query", + "name": "ids", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get links charts", + "tags": [ + "Links" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/links/charts/route.ts" + } + }, + "/api/me": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetMe", + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get me", + "tags": [ + "Account" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/me/route.ts" + } + }, + "/api/me/password": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostMePassword", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "currentPassword": { + "type": "string" + }, + "newPassword": { + "minLength": 8, + "type": "string" + } + }, + "required": [ + "currentPassword", + "newPassword" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update me password", + "tags": [ + "Account" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/me/password/route.ts" + } + }, + "/api/me/teams": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetMeTeams", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get me teams", + "tags": [ + "Account" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/me/teams/route.ts" + } + }, + "/api/me/websites": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetMeWebsites", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "includeTeams", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get me websites", + "tags": [ + "Account" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/me/websites/route.ts" + } + }, + "/api/pixels": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetPixels", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get pixels", + "tags": [ + "Pixels" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/pixels/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostPixels", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "anyOf": [ + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "name": { + "maxLength": 100, + "type": "string" + }, + "slug": { + "maxLength": 100, + "minLength": 8, + "type": "string" + }, + "teamId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "slug" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update pixels", + "tags": [ + "Pixels" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/pixels/route.ts" + } + }, + "/api/pixels/{pixelId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeletePixelsPixelId", + "parameters": [ + { + "in": "path", + "name": "pixelId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete pixels pixel id", + "tags": [ + "Pixels" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/pixels/[pixelId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetPixelsPixelId", + "parameters": [ + { + "in": "path", + "name": "pixelId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get pixels pixel id", + "tags": [ + "Pixels" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/pixels/[pixelId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostPixelsPixelId", + "parameters": [ + { + "in": "path", + "name": "pixelId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "slug": { + "maxLength": 100, + "minLength": 8, + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "500": { + "$ref": "#/components/responses/ServerErrorResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update pixels pixel id", + "tags": [ + "Pixels" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/pixels/[pixelId]/route.ts" + } + }, + "/api/pixels/{pixelId}/shares": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetPixelsPixelIdShares", + "parameters": [ + { + "in": "path", + "name": "pixelId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get pixels pixel id shares", + "tags": [ + "Pixels" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/pixels/[pixelId]/shares/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostPixelsPixelIdShares", + "parameters": [ + { + "in": "path", + "name": "pixelId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update pixels pixel id shares", + "tags": [ + "Pixels" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/pixels/[pixelId]/shares/route.ts" + } + }, + "/api/pixels/charts": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetPixelsCharts", + "parameters": [ + { + "in": "query", + "name": "ids", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get pixels charts", + "tags": [ + "Pixels" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/pixels/charts/route.ts" + } + }, + "/api/realtime/{websiteId}": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetRealtimeWebsiteId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get realtime website id", + "tags": [ + "Realtime" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/realtime/[websiteId]/route.ts" + } + }, + "/api/record": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostRecord", + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "properties": { + "payload": { + "properties": { + "events": { + "items": {}, + "maxItems": 200, + "type": "array" + }, + "timestamp": { + "type": "integer" + }, + "website": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "website", + "events" + ], + "type": "object" + }, + "type": { + "const": "record" + } + }, + "required": [ + "type", + "payload" + ], + "type": "object" + }, + { + "properties": { + "payload": { + "properties": { + "events": { + "items": { + "anyOf": [ + { + "properties": { + "pageH": { + "type": "number" + }, + "pageW": { + "type": "number" + }, + "pageX": { + "type": "number" + }, + "pageY": { + "type": "number" + }, + "timestamp": { + "type": "integer" + }, + "type": { + "const": "click" + }, + "url": { + "type": "string" + }, + "viewportH": { + "type": "number" + }, + "viewportW": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "url" + ], + "type": "object" + }, + { + "properties": { + "pageH": { + "type": "number" + }, + "pageW": { + "type": "number" + }, + "scrollPct": { + "type": "number" + }, + "timestamp": { + "type": "integer" + }, + "type": { + "const": "scroll" + }, + "url": { + "type": "string" + }, + "viewportH": { + "type": "number" + }, + "viewportW": { + "type": "number" + } + }, + "required": [ + "type", + "url" + ], + "type": "object" + } + ] + }, + "maxItems": 200, + "type": "array" + }, + "timestamp": { + "type": "integer" + }, + "website": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "website", + "events" + ], + "type": "object" + }, + "type": { + "const": "heatmap" + } + }, + "required": [ + "type", + "payload" + ], + "type": "object" + } + ] + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "403": { + "$ref": "#/components/responses/ForbiddenResponse" + }, + "413": { + "$ref": "#/components/responses/PayloadTooLargeResponse" + }, + "500": { + "$ref": "#/components/responses/ServerErrorResponse" + } + }, + "security": [], + "summary": "Create or update record", + "tags": [ + "Collection" + ], + "x-umami-audience": "collect", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/record/route.ts" + } + }, + "/api/reports": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetReports", + "parameters": [ + { + "in": "query", + "name": "websiteId", + "required": true, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get reports", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReports", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "description": { + "maxLength": 500, + "type": "string" + }, + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "type", + "name", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update reports", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/route.ts" + } + }, + "/api/reports/{reportId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteReportsReportId", + "parameters": [ + { + "in": "path", + "name": "reportId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete reports report id", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/[reportId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetReportsReportId", + "parameters": [ + { + "in": "path", + "name": "reportId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get reports report id", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/[reportId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsReportId", + "parameters": [ + { + "in": "path", + "name": "reportId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "description": { + "maxLength": 500, + "type": "string" + }, + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "type", + "name", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update reports report id", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/[reportId]/route.ts" + } + }, + "/api/reports/attribution": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsAttribution", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports attribution", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/attribution/route.ts" + } + }, + "/api/reports/breakdown": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsBreakdown", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports breakdown", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/breakdown/route.ts" + } + }, + "/api/reports/funnel": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsFunnel", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports funnel", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/funnel/route.ts" + } + }, + "/api/reports/goal": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsGoal", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports goal", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/goal/route.ts" + } + }, + "/api/reports/heatmap": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsHeatmap", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports heatmap", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/heatmap/route.ts" + } + }, + "/api/reports/journey": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsJourney", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports journey", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/journey/route.ts" + } + }, + "/api/reports/performance": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsPerformance", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports performance", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/performance/route.ts" + } + }, + "/api/reports/retention": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsRetention", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports retention", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/retention/route.ts" + } + }, + "/api/reports/revenue": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsRevenue", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports revenue", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/revenue/route.ts" + } + }, + "/api/reports/utm": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostReportsUtm", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "filters": { + "additionalProperties": true, + "type": "object" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "type": "string" + }, + "websiteId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "websiteId", + "filters", + "type", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Create or update reports utm", + "tags": [ + "Reports" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/reports/utm/route.ts" + } + }, + "/api/scripts/telemetry": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetScriptsTelemetry", + "responses": { + "200": { + "content": { + "text/javascript": { + "schema": { + "type": "string" + } + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + } + }, + "security": [], + "summary": "Get scripts telemetry", + "tags": [ + "Scripts" + ], + "x-umami-audience": "internal", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/scripts/telemetry/route.ts" + } + }, + "/api/send": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostSend", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "payload": { + "properties": { + "browser": { + "type": "string" + }, + "cls": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "data": { + "additionalProperties": true, + "type": "object" + }, + "device": { + "type": "string" + }, + "fcp": { + "maximum": 60000, + "minimum": 0, + "type": "number" + }, + "hostname": { + "type": "string" + }, + "id": { + "type": "string" + }, + "inp": { + "maximum": 60000, + "minimum": 0, + "type": "number" + }, + "ip": { + "type": "string" + }, + "language": { + "type": "string" + }, + "lcp": { + "maximum": 60000, + "minimum": 0, + "type": "number" + }, + "link": { + "format": "uuid", + "type": "string" + }, + "name": {}, + "os": { + "type": "string" + }, + "pixel": { + "format": "uuid", + "type": "string" + }, + "referrer": { + "type": "string" + }, + "screen": { + "type": "string" + }, + "tag": {}, + "timestamp": { + "type": "integer" + }, + "title": { + "type": "string" + }, + "ttfb": { + "maximum": 60000, + "minimum": 0, + "type": "number" + }, + "url": { + "type": "string" + }, + "userAgent": { + "type": "string" + }, + "website": { + "format": "uuid", + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "event", + "identify", + "performance" + ], + "type": "string" + } + }, + "required": [ + "type", + "payload" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "403": { + "$ref": "#/components/responses/ForbiddenResponse" + }, + "500": { + "$ref": "#/components/responses/ServerErrorResponse" + } + }, + "security": [], + "summary": "Create or update send", + "tags": [ + "Collection" + ], + "x-umami-audience": "collect", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/send/route.ts" + } + }, + "/api/share": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostShare", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "entityId": { + "format": "uuid", + "type": "string" + }, + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "shareType": { + "type": "integer" + }, + "slug": { + "maxLength": 100, + "type": "string" + } + }, + "required": [ + "entityId", + "shareType", + "name", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update share", + "tags": [ + "Shares" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/share/route.ts" + } + }, + "/api/share/{slug}": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetShareSlug", + "parameters": [ + { + "in": "path", + "name": "slug", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [], + "summary": "Get share slug", + "tags": [ + "Shares" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/share/[slug]/route.ts" + } + }, + "/api/share/id/{shareId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteShareIdShareId", + "parameters": [ + { + "in": "path", + "name": "shareId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete share id share id", + "tags": [ + "Shares" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/share/id/[shareId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetShareIdShareId", + "parameters": [ + { + "in": "path", + "name": "shareId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get share id share id", + "tags": [ + "Shares" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/share/id/[shareId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostShareIdShareId", + "parameters": [ + { + "in": "path", + "name": "shareId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "slug": { + "maxLength": 100, + "type": "string" + } + }, + "required": [ + "name", + "slug", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update share id share id", + "tags": [ + "Shares" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/share/id/[shareId]/route.ts" + } + }, + "/api/teams": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetTeams", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get teams", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostTeams", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 50, + "type": "string" + }, + "ownerId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update teams", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/route.ts" + } + }, + "/api/teams/{teamId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteTeamsTeamId", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete teams team id", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetTeamsTeamId", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get teams team id", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostTeamsTeamId", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "accessCode": { + "maxLength": 50, + "type": "string" + }, + "name": { + "maxLength": 50, + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update teams team id", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/route.ts" + } + }, + "/api/teams/{teamId}/boards": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetTeamsTeamIdBoards", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get teams team id boards", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/boards/route.ts" + } + }, + "/api/teams/{teamId}/links": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetTeamsTeamIdLinks", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get teams team id links", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/links/route.ts" + } + }, + "/api/teams/{teamId}/pixels": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetTeamsTeamIdPixels", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get teams team id pixels", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/pixels/route.ts" + } + }, + "/api/teams/{teamId}/users": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetTeamsTeamIdUsers", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get teams team id users", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/users/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostTeamsTeamIdUsers", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "role": { + "enum": [ + "team-member", + "team-view-only", + "team-manager" + ], + "type": "string" + }, + "userId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "userId", + "role" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update teams team id users", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/users/route.ts" + } + }, + "/api/teams/{teamId}/users/{userId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteTeamsTeamIdUsersUserId", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete teams team id users user id", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/users/[userId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetTeamsTeamIdUsersUserId", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get teams team id users user id", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/users/[userId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostTeamsTeamIdUsersUserId", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "role": { + "enum": [ + "team-member", + "team-view-only", + "team-manager" + ], + "type": "string" + } + }, + "required": [ + "role" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update teams team id users user id", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/users/[userId]/route.ts" + } + }, + "/api/teams/{teamId}/websites": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetTeamsTeamIdWebsites", + "parameters": [ + { + "in": "path", + "name": "teamId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get teams team id websites", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/[teamId]/websites/route.ts" + } + }, + "/api/teams/join": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostTeamsJoin", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "accessCode": { + "maxLength": 50, + "type": "string" + } + }, + "required": [ + "accessCode" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update teams join", + "tags": [ + "Teams" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/teams/join/route.ts" + } + }, + "/api/users": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostUsers", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "format": "uuid", + "type": "string" + }, + "password": { + "maxLength": 255, + "minLength": 8, + "type": "string" + }, + "role": { + "enum": [ + "admin", + "user", + "view-only" + ], + "type": "string" + }, + "username": { + "maxLength": 255, + "type": "string" + } + }, + "required": [ + "username", + "password", + "role" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update users", + "tags": [ + "Users" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/users/route.ts" + } + }, + "/api/users/{userId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteUsersUserId", + "parameters": [ + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete users user id", + "tags": [ + "Users" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/users/[userId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetUsersUserId", + "parameters": [ + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get users user id", + "tags": [ + "Users" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/users/[userId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostUsersUserId", + "parameters": [ + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "password": { + "maxLength": 255, + "minLength": 8, + "type": "string" + }, + "role": { + "enum": [ + "admin", + "user", + "view-only" + ], + "type": "string" + }, + "username": { + "maxLength": 255, + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update users user id", + "tags": [ + "Users" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/users/[userId]/route.ts" + } + }, + "/api/users/{userId}/teams": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetUsersUserIdTeams", + "parameters": [ + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get users user id teams", + "tags": [ + "Users" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/users/[userId]/teams/route.ts" + } + }, + "/api/users/{userId}/websites": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetUsersUserIdWebsites", + "parameters": [ + { + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "orderBy", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortDescending", + "required": false, + "schema": { + "enum": [ + "true", + "false" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "includeTeams", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Get users user id websites", + "tags": [ + "Users" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/users/[userId]/websites/route.ts" } }, "/api/websites": { @@ -789,7 +8055,9 @@ "tags": [ "Websites" ], - "x-umami-audience": "public" + "x-umami-audience": "public", + "x-umami-contract": "explicit", + "x-umami-source": "src/app/api/websites/contract.ts" }, "post": { "operationId": "createWebsite", @@ -830,7 +8098,9 @@ "tags": [ "Websites" ], - "x-umami-audience": "public" + "x-umami-audience": "public", + "x-umami-contract": "explicit", + "x-umami-source": "src/app/api/websites/contract.ts" } }, "/api/websites/{websiteId}": { @@ -874,7 +8144,9 @@ "tags": [ "Websites" ], - "x-umami-audience": "public" + "x-umami-audience": "public", + "x-umami-contract": "explicit", + "x-umami-source": "src/app/api/websites/[websiteId]/contract.ts" }, "get": { "operationId": "getWebsite", @@ -927,7 +8199,9 @@ "tags": [ "Websites" ], - "x-umami-audience": "public" + "x-umami-audience": "public", + "x-umami-contract": "explicit", + "x-umami-source": "src/app/api/websites/[websiteId]/contract.ts" }, "post": { "operationId": "updateWebsite", @@ -985,14 +8259,13579 @@ "tags": [ "Websites" ], - "x-umami-audience": "public" + "x-umami-audience": "public", + "x-umami-contract": "explicit", + "x-umami-source": "src/app/api/websites/[websiteId]/contract.ts" + } + }, + "/api/websites/{websiteId}/active": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdActive", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id active", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/active/route.ts" + } + }, + "/api/websites/{websiteId}/annotations": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdAnnotations", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id annotations", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/annotations/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostWebsitesWebsiteIdAnnotations", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "allDay": { + "type": "boolean" + }, + "date": { + "format": "date-time", + "type": "string" + }, + "note": { + "maxLength": 500, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "date", + "note" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update websites website id annotations", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/annotations/route.ts" + } + }, + "/api/websites/{websiteId}/annotations/{annotationId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteWebsitesWebsiteIdAnnotationsAnnotationId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "annotationId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete websites website id annotations annotation id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/annotations/[annotationId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdAnnotationsAnnotationId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "annotationId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id annotations annotation id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/annotations/[annotationId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostWebsitesWebsiteIdAnnotationsAnnotationId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "annotationId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "allDay": { + "type": "boolean" + }, + "date": { + "format": "date-time", + "type": "string" + }, + "note": { + "maxLength": 500, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "date", + "note" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update websites website id annotations annotation id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/annotations/[annotationId]/route.ts" + } + }, + "/api/websites/{websiteId}/daterange": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdDaterange", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id daterange", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/daterange/route.ts" + } + }, + "/api/websites/{websiteId}/event-data": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventData", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data/route.ts" + } + }, + "/api/websites/{websiteId}/event-data-pivot": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataPivot", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "eventName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data pivot", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data-pivot/route.ts" + } + }, + "/api/websites/{websiteId}/event-data-pivot/array-series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataPivotArraySeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "eventName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data pivot array series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data-pivot/array-series/route.ts" + } + }, + "/api/websites/{websiteId}/event-data-pivot/date-series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataPivotDateSeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "eventName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data pivot date series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data-pivot/date-series/route.ts" + } + }, + "/api/websites/{websiteId}/event-data-pivot/numeric-series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataPivotNumericSeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "eventName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "metric", + "required": false, + "schema": { + "enum": [ + "sum", + "avg", + "count" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data pivot numeric series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data-pivot/numeric-series/route.ts" + } + }, + "/api/websites/{websiteId}/event-data-pivot/numeric-stats": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataPivotNumericStats", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "eventName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data pivot numeric stats", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data-pivot/numeric-stats/route.ts" + } + }, + "/api/websites/{websiteId}/event-data-pivot/property-series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataPivotPropertySeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "eventName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data pivot property series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data-pivot/property-series/route.ts" + } + }, + "/api/websites/{websiteId}/event-data/{eventId}": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataEventId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "eventId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data event id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data/[eventId]/route.ts" + } + }, + "/api/websites/{websiteId}/event-data/events": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataEvents", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data events", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data/events/route.ts" + } + }, + "/api/websites/{websiteId}/event-data/fields": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataFields", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "eventName", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data fields", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data/fields/route.ts" + } + }, + "/api/websites/{websiteId}/event-data/properties": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataProperties", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data properties", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data/properties/route.ts" + } + }, + "/api/websites/{websiteId}/event-data/stats": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataStats", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data stats", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data/stats/route.ts" + } + }, + "/api/websites/{websiteId}/event-data/values": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventDataValues", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "eventName", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "dataType", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id event data values", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/event-data/values/route.ts" + } + }, + "/api/websites/{websiteId}/events": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEvents", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id events", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/events/route.ts" + } + }, + "/api/websites/{websiteId}/events/series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventsSeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id events series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/events/series/route.ts" + } + }, + "/api/websites/{websiteId}/events/stats": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdEventsStats", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id events stats", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/events/stats/route.ts" + } + }, + "/api/websites/{websiteId}/export": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdExport", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "function toString() { [native code] }": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id export", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/export/route.ts" + } + }, + "/api/websites/{websiteId}/metrics": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdMetrics", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "type", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "offset", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id metrics", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/metrics/route.ts" + } + }, + "/api/websites/{websiteId}/metrics/expanded": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdMetricsExpanded", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "type", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "offset", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id metrics expanded", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/metrics/expanded/route.ts" + } + }, + "/api/websites/{websiteId}/pageviews": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdPageviews", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id pageviews", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/pageviews/route.ts" + } + }, + "/api/websites/{websiteId}/recorder": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdRecorder", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + } + }, + "security": [], + "summary": "Get websites website id recorder", + "tags": [ + "Websites" + ], + "x-umami-audience": "collect", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/recorder/route.ts" + } + }, + "/api/websites/{websiteId}/replays": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdReplays", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "minDuration", + "required": false, + "schema": { + "minimum": 0, + "type": "integer" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id replays", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/replays/route.ts" + } + }, + "/api/websites/{websiteId}/replays/{replayId}": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdReplaysReplayId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "replayId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id replays replay id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/replays/[replayId]/route.ts" + } + }, + "/api/websites/{websiteId}/replays/saved": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdReplaysSaved", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id replays saved", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/replays/saved/route.ts" + } + }, + "/api/websites/{websiteId}/replays/saved/{replayId}": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdReplaysSavedReplayId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "replayId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id replays saved replay id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/replays/saved/[replayId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostWebsitesWebsiteIdReplaysSavedReplayId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "replayId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "isSaved": { + "type": "boolean" + }, + "name": { + "maxLength": 100, + "type": "string" + } + }, + "required": [ + "isSaved" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update websites website id replays saved replay id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/replays/saved/[replayId]/route.ts" + } + }, + "/api/websites/{websiteId}/reports": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdReports", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id reports", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/reports/route.ts" + } + }, + "/api/websites/{websiteId}/reset": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostWebsitesWebsiteIdReset", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update websites website id reset", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/reset/route.ts" + } + }, + "/api/websites/{websiteId}/revenue/chart": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdRevenueChart", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "currency", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id revenue chart", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/revenue/chart/route.ts" + } + }, + "/api/websites/{websiteId}/revenue/metrics": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdRevenueMetrics", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "type", + "required": true, + "schema": { + "enum": [ + "country", + "region", + "referrer", + "channel" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "currency", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id revenue metrics", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/revenue/metrics/route.ts" + } + }, + "/api/websites/{websiteId}/revenue/sessions": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdRevenueSessions", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "currency", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id revenue sessions", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/revenue/sessions/route.ts" + } + }, + "/api/websites/{websiteId}/revenue/stats": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdRevenueStats", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "currency", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id revenue stats", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/revenue/stats/route.ts" + } + }, + "/api/websites/{websiteId}/segments": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSegments", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "type", + "required": true, + "schema": { + "enum": [ + "segment", + "cohort" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id segments", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/segments/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostWebsitesWebsiteIdSegments", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "properties": { + "action": { + "properties": { + "type": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + "dateRange": { + "type": "string" + }, + "filters": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "match": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "segment", + "cohort" + ], + "type": "string" + } + }, + "required": [ + "type", + "name", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update websites website id segments", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/segments/route.ts" + } + }, + "/api/websites/{websiteId}/segments/{segmentId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteWebsitesWebsiteIdSegmentsSegmentId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "segmentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete websites website id segments segment id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/segments/[segmentId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSegmentsSegmentId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "segmentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id segments segment id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/segments/[segmentId]/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostWebsitesWebsiteIdSegmentsSegmentId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "segmentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + }, + "type": { + "enum": [ + "segment", + "cohort" + ], + "type": "string" + } + }, + "required": [ + "type", + "name", + "parameters" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update websites website id segments segment id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/segments/[segmentId]/route.ts" + } + }, + "/api/websites/{websiteId}/session-data-pivot": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataPivot", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data pivot", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data-pivot/route.ts" + } + }, + "/api/websites/{websiteId}/session-data/array-series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataArraySeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data array series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data/array-series/route.ts" + } + }, + "/api/websites/{websiteId}/session-data/date-series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataDateSeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data date series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data/date-series/route.ts" + } + }, + "/api/websites/{websiteId}/session-data/numeric-series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataNumericSeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "metric", + "required": false, + "schema": { + "enum": [ + "sum", + "avg", + "count" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data numeric series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data/numeric-series/route.ts" + } + }, + "/api/websites/{websiteId}/session-data/numeric-stats": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataNumericStats", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data numeric stats", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data/numeric-stats/route.ts" + } + }, + "/api/websites/{websiteId}/session-data/properties": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataProperties", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data properties", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data/properties/route.ts" + } + }, + "/api/websites/{websiteId}/session-data/property-series": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataPropertySeries", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data property series", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data/property-series/route.ts" + } + }, + "/api/websites/{websiteId}/session-data/stats": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataStats", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data stats", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data/stats/route.ts" + } + }, + "/api/websites/{websiteId}/session-data/values": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionDataValues", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "propertyName", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "dataType", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id session data values", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/session-data/values/route.ts" + } + }, + "/api/websites/{websiteId}/sessions": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessions", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id sessions", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/sessions/route.ts" + } + }, + "/api/websites/{websiteId}/sessions/{sessionId}": { + "delete": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredDeleteWebsitesWebsiteIdSessionsSessionId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "sessionId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ok" + } + } + }, + "description": "The operation completed successfully." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Delete websites website id sessions session id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/sessions/[sessionId]/route.ts" + }, + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionsSessionId", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "sessionId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + }, + "404": { + "$ref": "#/components/responses/NotFoundResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id sessions session id", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/sessions/[sessionId]/route.ts" + } + }, + "/api/websites/{websiteId}/sessions/{sessionId}/activity": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionsSessionIdActivity", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "sessionId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id sessions session id activity", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/sessions/[sessionId]/activity/route.ts" + } + }, + "/api/websites/{websiteId}/sessions/{sessionId}/properties": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionsSessionIdProperties", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "sessionId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id sessions session id properties", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/sessions/[sessionId]/properties/route.ts" + } + }, + "/api/websites/{websiteId}/sessions/{sessionId}/replays": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionsSessionIdReplays", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "sessionId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id sessions session id replays", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/sessions/[sessionId]/replays/route.ts" + } + }, + "/api/websites/{websiteId}/sessions/stats": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionsStats", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id sessions stats", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/sessions/stats/route.ts" + } + }, + "/api/websites/{websiteId}/sessions/weekly": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdSessionsWeekly", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "timezone", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id sessions weekly", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/sessions/weekly/route.ts" + } + }, + "/api/websites/{websiteId}/shares": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdShares", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "maxResults", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id shares", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/shares/route.ts" + }, + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostWebsitesWebsiteIdShares", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "maxLength": 200, + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update websites website id shares", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/shares/route.ts" + } + }, + "/api/websites/{websiteId}/stats": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdStats", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "path", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "referrer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "os", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "browser", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "device", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "country", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "region", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "city", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "hostname", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "distinctId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "event", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmSource", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmMedium", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmCampaign", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmContent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "utmTerm", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "excludeBounce", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "segment", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "cohort", + "required": false, + "schema": { + "format": "uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "eventType", + "required": false, + "schema": { + "minimum": 1, + "type": "integer" + } + }, + { + "in": "query", + "name": "match", + "required": false, + "schema": { + "enum": [ + "all", + "any" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id stats", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/stats/route.ts" + } + }, + "/api/websites/{websiteId}/transfer": { + "post": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredPostWebsitesWebsiteIdTransfer", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "teamId": { + "format": "uuid", + "type": "string" + }, + "userId": { + "format": "uuid", + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "summary": "Create or update websites website id transfer", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/transfer/route.ts" + } + }, + "/api/websites/{websiteId}/values": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesWebsiteIdValues", + "parameters": [ + { + "in": "path", + "name": "websiteId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "startDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "endDate", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "unit", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "compare", + "required": false, + "schema": { + "enum": [ + "prev", + "yoy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "type", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites website id values", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/[websiteId]/values/route.ts" + } + }, + "/api/websites/charts": { + "get": { + "description": "Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.", + "operationId": "inferredGetWebsitesCharts", + "parameters": [ + { + "in": "query", + "name": "ids", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "startAt", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "endAt", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "timezone", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema." + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedResponse" + } + }, + "security": [ + { + "bearerAuth": [] + }, + { + "shareContext": [], + "shareToken": [] + } + ], + "summary": "Get websites charts", + "tags": [ + "Websites" + ], + "x-umami-audience": "public", + "x-umami-contract": "inferred", + "x-umami-source": "src/app/api/websites/charts/route.ts" } } }, "tags": [ + { + "name": "Account" + }, + { + "name": "Administration" + }, { "name": "Authentication" }, + { + "name": "Boards" + }, + { + "name": "Collection" + }, + { + "name": "Configuration" + }, + { + "name": "Dashboard" + }, + { + "name": "Links" + }, + { + "name": "Pixels" + }, + { + "name": "Realtime" + }, + { + "name": "Reports" + }, + { + "name": "Scripts" + }, + { + "name": "Shares" + }, + { + "name": "System" + }, + { + "name": "Teams" + }, + { + "name": "Two-factor authentication" + }, + { + "name": "Users" + }, { "name": "Websites" } diff --git a/scripts/check-openapi.ts b/scripts/check-openapi.ts index 328a3408d..f3f4373a5 100644 --- a/scripts/check-openapi.ts +++ b/scripts/check-openapi.ts @@ -7,9 +7,10 @@ import { serializeOpenApiDocument } from '@/openapi/serialize'; const projectRoot = process.cwd(); const outputFile = path.join(projectRoot, 'public', 'openapi.json'); -const strict = process.argv.includes('--strict') || process.env.OPENAPI_REQUIRE_COMPLETE === '1'; +const requireExplicit = + process.argv.includes('--explicit') || process.env.OPENAPI_REQUIRE_EXPLICIT === '1'; const verbose = process.argv.includes('--verbose'); -const { document, coverage } = await buildOpenApiDocument('public', projectRoot); +const { document, coverage } = await buildOpenApiDocument('all', projectRoot); const expected = serializeOpenApiDocument(document); let actual = ''; @@ -36,8 +37,13 @@ if (verbose && coverage.missing.length) { }); } -if (strict && coverage.missing.length) { - console.error('Strict OpenAPI coverage requires an explicit contract for every API operation.'); +if (coverage.missingGenerated.length) { + console.error('OpenAPI generation must include every discovered API operation.'); + failed = true; +} + +if (requireExplicit && coverage.missing.length) { + console.error('Explicit OpenAPI coverage requires a hand-authored contract for every operation.'); failed = true; } diff --git a/scripts/generate-openapi.ts b/scripts/generate-openapi.ts index 0abe894d0..7f220a3ee 100644 --- a/scripts/generate-openapi.ts +++ b/scripts/generate-openapi.ts @@ -6,7 +6,7 @@ import { serializeOpenApiDocument } from '@/openapi/serialize'; const projectRoot = process.cwd(); const outputFile = path.join(projectRoot, 'public', 'openapi.json'); -const { document, coverage } = await buildOpenApiDocument('public', projectRoot); +const { document, coverage } = await buildOpenApiDocument('all', projectRoot); await mkdir(path.dirname(outputFile), { recursive: true }); await writeFile(outputFile, serializeOpenApiDocument(document), 'utf8'); diff --git a/src/openapi/README.md b/src/openapi/README.md index 604d4b8c4..760e1736c 100644 --- a/src/openapi/README.md +++ b/src/openapi/README.md @@ -1,15 +1,16 @@ # OpenAPI contracts -Umami generates `public/openapi.json` from Zod-backed contracts colocated with App Router API -handlers. +Umami generates `public/openapi.json` for every App Router API handler. It statically infers a +baseline contract from route source and replaces that baseline with a colocated, Zod-backed +contract wherever one exists. ## Commands - `pnpm openapi:generate` regenerates the public OpenAPI document. - `pnpm openapi:check` validates contract alignment and checks that the generated file is current. -- `pnpm openapi:check --strict` also fails while any non-OPTIONS API route lacks an explicit +- `pnpm openapi:check --explicit` also fails while any non-OPTIONS API route lacks a hand-authored contract. -- `pnpm openapi:check --verbose` lists routes that still need contracts. +- `pnpm openapi:check --verbose` lists operations that still use inferred contracts. The normal and Docker builds run the generator before the Next.js build. CI runs the check before tests and build steps. @@ -23,12 +24,18 @@ request and response shapes with Zod, and import the same request schema into th Contract modules must remain safe to import from a build script. They must not import route handlers, database clients, Redis clients, or modules with environment-dependent side effects. -Every operation declares an audience: +The generated artifact contains all audiences. Every operation declares one of: -- `public` operations are emitted to `public/openapi.json`. -- `internal` operations are available when building an unfiltered document. +- `public` operations are intended for API consumers. +- `internal` operations support the Umami application or deployment. - `collect` operations identify tracker ingestion APIs. Route paths and HTTP methods are discovered independently from `src/app/api/**/route.ts`. The check -rejects duplicate contracts, duplicate operation IDs, orphaned contracts, and mismatched dynamic -path parameters. +requires all discovered non-OPTIONS operations in the artifact and rejects duplicate contracts, +duplicate operation IDs, orphaned contracts, and mismatched dynamic path parameters. + +Inferred operations are marked with `x-umami-contract: inferred` and their source file. The inference +layer extracts path parameters, Zod request fields, authentication, response status helpers, and +response media types without importing route modules. Unknown response bodies remain free-form JSON +instead of being assigned an unverified shape. Explicit contracts are marked `explicit` and remain +the way to add exact response schemas, examples, and curated prose. diff --git a/src/openapi/contracts.ts b/src/openapi/contracts.ts index 711c1a908..52666e0ee 100644 --- a/src/openapi/contracts.ts +++ b/src/openapi/contracts.ts @@ -25,7 +25,7 @@ export async function loadApiContracts( const source = path.relative(projectRoot, contractFile).replaceAll(path.sep, '/'); module.operations.forEach(operation => { - contracts.push({ ...operation, source }); + contracts.push({ ...operation, source, origin: 'explicit' }); }); } diff --git a/src/openapi/coverage.ts b/src/openapi/coverage.ts index 592d6ebab..5b15efd30 100644 --- a/src/openapi/coverage.ts +++ b/src/openapi/coverage.ts @@ -8,7 +8,9 @@ import { export interface ContractCoverage { discovered: DiscoveredApiOperation[]; contracted: LoadedApiOperationContract[]; + generated: LoadedApiOperationContract[]; missing: DiscoveredApiOperation[]; + missingGenerated: DiscoveredApiOperation[]; orphaned: LoadedApiOperationContract[]; duplicateContracts: string[]; duplicateOperationIds: string[]; @@ -23,11 +25,22 @@ function getContractPathParameters(contract: ApiOperationContract) { const schema = contract.operation.requestParams?.path as { shape?: unknown } | undefined; const shape = schema?.shape; - if (!shape || typeof shape !== 'object') { - return []; + if (shape && typeof shape === 'object') { + return Object.keys(shape).sort(); } - return Object.keys(shape).sort(); + return (contract.operation.parameters ?? []) + .filter( + parameter => + parameter && + typeof parameter === 'object' && + 'in' in parameter && + parameter.in === 'path' && + 'name' in parameter && + typeof parameter.name === 'string', + ) + .map(parameter => ('name' in parameter ? (parameter.name as string) : '')) + .sort(); } function arraysEqual(left: string[], right: string[]) { @@ -37,13 +50,14 @@ function arraysEqual(left: string[], right: string[]) { export function analyzeContractCoverage( discovered: DiscoveredApiOperation[], contracted: LoadedApiOperationContract[], + generated: LoadedApiOperationContract[] = contracted, ): ContractCoverage { const relevantRoutes = discovered.filter(operation => operation.method !== 'options'); const discoveredKeys = new Set(relevantRoutes.map(getOperationKey)); const contractsByKey = new Map(); const contractsByOperationId = new Map(); - contracted.forEach(contract => { + generated.forEach(contract => { const key = getOperationKey(contract); const operationId = contract.operation.operationId; @@ -69,11 +83,13 @@ export function analyzeContractCoverage( ) .sort(); const contractedKeys = new Set(contractsByKey.keys()); - const missing = relevantRoutes.filter( + const explicitKeys = new Set(contracted.map(getOperationKey)); + const missing = relevantRoutes.filter(operation => !explicitKeys.has(getOperationKey(operation))); + const missingGenerated = relevantRoutes.filter( operation => !contractedKeys.has(getOperationKey(operation)), ); - const orphaned = contracted.filter(contract => !discoveredKeys.has(getOperationKey(contract))); - const pathParameterMismatches = contracted + const orphaned = generated.filter(contract => !discoveredKeys.has(getOperationKey(contract))); + const pathParameterMismatches = generated .map(contract => { const expected = getExpectedPathParameters(contract.path); const actual = getContractPathParameters(contract); @@ -90,7 +106,9 @@ export function analyzeContractCoverage( return { discovered: relevantRoutes, contracted, + generated, missing, + missingGenerated, orphaned, duplicateContracts, duplicateOperationIds, @@ -107,9 +125,13 @@ export function getCoverageErrors(coverage: ContractCoverage) { `Contract does not match a route: ${getOperationKey(contract)} (${contract.source})`, ), ...coverage.pathParameterMismatches.map(message => `Path parameter mismatch: ${message}`), + ...coverage.missingGenerated.map( + operation => + `Generated spec is missing route: ${getOperationKey(operation)} (${operation.source})`, + ), ]; } export function formatCoverageSummary(coverage: ContractCoverage) { - return `${coverage.contracted.length}/${coverage.discovered.length} API operations have explicit OpenAPI contracts; ${coverage.missing.length} remain.`; + return `${coverage.generated.length}/${coverage.discovered.length} API operations are included in the generated spec (${coverage.contracted.length} explicit, ${coverage.missing.length} source-inferred).`; } diff --git a/src/openapi/discover.ts b/src/openapi/discover.ts index 114d19847..bf720bde3 100644 --- a/src/openapi/discover.ts +++ b/src/openapi/discover.ts @@ -2,6 +2,7 @@ import { readdir, readFile } from 'node:fs/promises'; import path from 'node:path'; import ts from 'typescript'; import { API_HTTP_METHODS, type ApiHttpMethod } from '@/openapi/operation'; +import { analyzeSourceOperation, type SourceOperationAnalysis } from '@/openapi/source-analysis'; const ROUTE_FILE_PATTERN = /^route\.(?:js|jsx|ts|tsx)$/; const METHOD_NAMES = new Set(API_HTTP_METHODS.map(method => method.toUpperCase())); @@ -10,6 +11,7 @@ export interface DiscoveredApiOperation { method: ApiHttpMethod; path: `/${string}`; source: string; + analysis: SourceOperationAnalysis; } async function walk(directory: string, predicate: (name: string) => boolean): Promise { @@ -115,7 +117,12 @@ export async function discoverApiOperations( const relativeSource = path.relative(projectRoot, routeFile).replaceAll(path.sep, '/'); getExportedMethods(source).forEach(method => { - operations.push({ method, path: routePath, source: relativeSource }); + operations.push({ + method, + path: routePath, + source: relativeSource, + analysis: analyzeSourceOperation(source, method), + }); }); } diff --git a/src/openapi/document.ts b/src/openapi/document.ts index 595de64bf..843a69ca4 100644 --- a/src/openapi/document.ts +++ b/src/openapi/document.ts @@ -8,6 +8,7 @@ import { getCoverageErrors, } from '@/openapi/coverage'; import { discoverApiOperations } from '@/openapi/discover'; +import { inferApiContracts } from '@/openapi/infer'; import type { ApiAudience } from '@/openapi/operation'; import { getSecurityRequirements, securitySchemes } from '@/openapi/security'; @@ -46,12 +47,14 @@ export async function buildOpenApiDocument( audience: DocumentAudience = 'public', projectRoot = process.cwd(), ): Promise { - const [contracts, discovered, version] = await Promise.all([ + const [explicitContracts, discovered, version] = await Promise.all([ loadApiContracts(projectRoot), discoverApiOperations(projectRoot), getPackageVersion(projectRoot), ]); - const coverage = analyzeContractCoverage(discovered, contracts); + const inferredContracts = inferApiContracts(discovered, explicitContracts); + const contracts = [...explicitContracts, ...inferredContracts]; + const coverage = analyzeContractCoverage(discovered, explicitContracts, contracts); const errors = getCoverageErrors(coverage); if (errors.length) { @@ -77,6 +80,8 @@ export async function buildOpenApiDocument( ...contract.operation, security: getSecurityRequirements(contract.auth), 'x-umami-audience': contract.audience, + 'x-umami-contract': contract.origin, + 'x-umami-source': contract.source, }; Object.assign(pathItem, { [contract.method]: operation }); @@ -89,7 +94,7 @@ export async function buildOpenApiDocument( title: 'Umami API', version, description: - 'REST API for Umami analytics. Self-hosted deployments serve these paths beneath their configured BASE_PATH.', + 'REST API for Umami analytics. Every App Router API operation is included. Operations marked with x-umami-contract: inferred are generated from handler source; colocated explicit contracts provide curated descriptions and exact response models. Self-hosted deployments serve these paths beneath their configured BASE_PATH.', license: { name: 'MIT', identifier: 'MIT', diff --git a/src/openapi/infer.ts b/src/openapi/infer.ts new file mode 100644 index 000000000..9efd7fd43 --- /dev/null +++ b/src/openapi/infer.ts @@ -0,0 +1,227 @@ +import type { + ZodOpenApiOperationObject, + ZodOpenApiParameterObject, + ZodOpenApiResponseObject, + ZodOpenApiResponsesObject, + ZodOpenApiSchemaObject, +} from 'zod-openapi'; +import type { DiscoveredApiOperation } from '@/openapi/discover'; +import type { ApiAudience, ApiHttpMethod, LoadedApiOperationContract } from '@/openapi/operation'; +import { getOperationKey } from '@/openapi/operation'; +import { + badRequestResponse, + forbiddenResponse, + notFoundResponse, + okSchema, + payloadTooLargeResponse, + serverErrorResponse, + serviceUnavailableResponse, + unauthorizedResponse, +} from '@/openapi/schemas'; +import type { InferredOpenApiSchema } from '@/openapi/source-analysis'; + +const errorResponses: Record = { + 400: badRequestResponse, + 401: unauthorizedResponse, + 403: forbiddenResponse, + 404: notFoundResponse, + 413: payloadTooLargeResponse, + 500: serverErrorResponse, + 503: serviceUnavailableResponse, +}; + +const TAGS: Record = { + '2fa': 'Two-factor authentication', + admin: 'Administration', + auth: 'Authentication', + batch: 'Collection', + boards: 'Boards', + config: 'Configuration', + dashboard: 'Dashboard', + heartbeat: 'System', + links: 'Links', + me: 'Account', + pixels: 'Pixels', + realtime: 'Realtime', + record: 'Collection', + reports: 'Reports', + scripts: 'Scripts', + send: 'Collection', + share: 'Shares', + teams: 'Teams', + users: 'Users', + websites: 'Websites', +}; + +function getPathSegments(path: string) { + return path.split('/').filter(Boolean).slice(1); +} + +function words(value: string) { + return value + .replace(/[{}]/g, '') + .replace(/([a-z0-9])([A-Z])/g, '$1 $2') + .replace(/[-_]+/g, ' ') + .toLowerCase(); +} + +function pascalCase(value: string) { + return words(value) + .split(' ') + .filter(Boolean) + .map(word => `${word[0]?.toUpperCase()}${word.slice(1)}`) + .join(''); +} + +function getOperationId(method: ApiHttpMethod, path: string) { + return `inferred${pascalCase(method)}${getPathSegments(path).map(pascalCase).join('')}`; +} + +function getSummary(method: ApiHttpMethod, path: string) { + const action: Record = { + get: 'Get', + post: 'Create or update', + put: 'Replace', + patch: 'Update', + delete: 'Delete', + head: 'Inspect', + options: 'Inspect options for', + }; + const label = getPathSegments(path) + .map(segment => words(segment)) + .join(' '); + + return `${action[method]} ${label}`; +} + +function getAudience(path: string): ApiAudience { + if ( + path === '/api/send' || + path === '/api/batch' || + path === '/api/record' || + path.endsWith('/recorder') + ) { + return 'collect'; + } + + if ( + ['/api/admin', '/api/config', '/api/dashboard', '/api/heartbeat', '/api/scripts'].some( + prefix => path === prefix || path.startsWith(`${prefix}/`), + ) + ) { + return 'internal'; + } + + return 'public'; +} + +function getTag(path: string) { + const root = getPathSegments(path)[0] ?? 'api'; + return TAGS[root] ?? pascalCase(root); +} + +function getPathParameters(path: string): ZodOpenApiParameterObject[] { + return [...path.matchAll(/\{([^}]+)}/g)].map(match => ({ + name: match[1], + in: 'path', + required: true, + schema: { type: 'string' }, + })); +} + +function getQueryParameters(schema: InferredOpenApiSchema | undefined) { + if (schema?.type !== 'object' || !schema.properties) { + return []; + } + + const required = new Set((schema.required ?? []) as string[]); + + return Object.entries(schema.properties).map(([name, propertySchema]) => ({ + name, + in: 'query' as const, + required: required.has(name), + schema: propertySchema, + })); +} + +function successResponse(mediaType: string, returnsOk: boolean): ZodOpenApiResponseObject { + return { + description: returnsOk + ? 'The operation completed successfully.' + : 'Successful response. The response shape is inferred as free-form because the handler does not expose a reusable response schema.', + content: { + [mediaType]: { + schema: returnsOk + ? okSchema + : mediaType === 'application/json' + ? ({} as ZodOpenApiSchemaObject) + : ({ type: 'string' } as ZodOpenApiSchemaObject), + }, + }, + }; +} + +function getResponses(operation: DiscoveredApiOperation): ZodOpenApiResponsesObject { + const responses: ZodOpenApiResponsesObject = {}; + + operation.analysis.responseStatuses.forEach(status => { + const response = errorResponses[status]; + responses[`${status}` as `${1 | 2 | 3 | 4 | 5}${string}`] = + response ?? + successResponse(operation.analysis.responseMediaType, operation.analysis.returnsOk); + }); + + return responses; +} + +function getOperation(operation: DiscoveredApiOperation): ZodOpenApiOperationObject { + const { analysis, method, path, source } = operation; + const parameters = [ + ...getPathParameters(path), + ...(method === 'get' ? getQueryParameters(analysis.requestSchema) : []), + ]; + const requestBody = + method !== 'get' && analysis.hasRequestSchema + ? { + required: true, + content: { + 'application/json': { + schema: analysis.requestSchema ?? ({} as ZodOpenApiSchemaObject), + }, + }, + } + : undefined; + + return { + operationId: getOperationId(method, path), + summary: getSummary(method, path), + description: + 'Generated from the App Router handler and its request-validation source. Add a colocated contract.ts to supply exact response models and curated documentation.', + tags: [getTag(path)], + ...(parameters.length ? { parameters } : {}), + ...(requestBody ? { requestBody } : {}), + responses: getResponses(operation), + 'x-umami-source': source, + } as ZodOpenApiOperationObject; +} + +export function inferApiContracts( + discovered: DiscoveredApiOperation[], + explicit: LoadedApiOperationContract[], +): LoadedApiOperationContract[] { + const explicitKeys = new Set(explicit.map(getOperationKey)); + + return discovered + .filter( + operation => operation.method !== 'options' && !explicitKeys.has(getOperationKey(operation)), + ) + .map(operation => ({ + method: operation.method, + path: operation.path, + audience: getAudience(operation.path), + auth: operation.analysis.auth, + operation: getOperation(operation), + source: operation.source, + origin: 'inferred', + })); +} diff --git a/src/openapi/operation.ts b/src/openapi/operation.ts index 0908102c1..baffc2552 100644 --- a/src/openapi/operation.ts +++ b/src/openapi/operation.ts @@ -24,6 +24,7 @@ export interface ApiOperationContract { export interface LoadedApiOperationContract extends ApiOperationContract { source: string; + origin: 'explicit' | 'inferred'; } export function defineOperation(contract: T): T { diff --git a/src/openapi/source-analysis.ts b/src/openapi/source-analysis.ts new file mode 100644 index 000000000..db14c23c2 --- /dev/null +++ b/src/openapi/source-analysis.ts @@ -0,0 +1,744 @@ +import ts from 'typescript'; +import type { ApiAuth, ApiHttpMethod } from '@/openapi/operation'; + +export interface InferredOpenApiSchema { + type?: string; + format?: string; + enum?: unknown[]; + const?: unknown; + properties?: Record; + required?: string[]; + items?: InferredOpenApiSchema; + prefixItems?: InferredOpenApiSchema[]; + anyOf?: InferredOpenApiSchema[]; + allOf?: InferredOpenApiSchema[]; + additionalProperties?: boolean | InferredOpenApiSchema; + minimum?: number; + maximum?: number; + exclusiveMinimum?: number; + minLength?: number; + maxLength?: number; + minItems?: number; + maxItems?: number; + [key: string]: unknown; +} + +type Schema = InferredOpenApiSchema; + +export interface SourceOperationAnalysis { + auth: ApiAuth; + hasRequestSchema: boolean; + requestSchema?: Schema; + responseStatuses: number[]; + responseMediaType: string; + returnsOk: boolean; +} + +interface InferredSchema { + schema: Schema; + optional: boolean; +} + +const RESPONSE_STATUSES: Record = { + json: 200, + ok: 200, + badRequest: 400, + unauthorized: 401, + forbidden: 403, + notFound: 404, + payloadTooLarge: 413, + serverError: 500, + serviceUnavailable: 503, +}; + +const stringSchema = (): Schema => ({ type: 'string' }); +const numberSchema = (): Schema => ({ type: 'number' }); +const booleanSchema = (): Schema => ({ type: 'boolean' }); +const unknownSchema = (): Schema => ({}); + +function required(schema: Schema): InferredSchema { + return { schema, optional: false }; +} + +function objectSchema( + properties: Record, + requiredProperties: string[] = Object.keys(properties), +): Schema { + return { + type: 'object', + properties, + ...(requiredProperties.length ? { required: requiredProperties } : {}), + }; +} + +const knownSchemas: Record InferredSchema> = { + timezoneParam: () => required(stringSchema()), + unitParam: () => required(stringSchema()), + userRoleParam: () => required({ type: 'string', enum: ['admin', 'user', 'view-only'] }), + teamRoleParam: () => + required({ type: 'string', enum: ['team-member', 'team-view-only', 'team-manager'] }), + anyObjectParam: () => required({ type: 'object', additionalProperties: true }), + urlOrPathParam: () => required(stringSchema()), + fieldsParam: () => required(stringSchema()), + reportTypeParam: () => required(stringSchema()), + operatorParam: () => required(stringSchema()), + segmentTypeParam: () => required({ type: 'string', enum: ['segment', 'cohort'] }), + annotationSchema: () => + required( + objectSchema( + { + date: { type: 'string', format: 'date-time' }, + allDay: booleanSchema(), + note: { type: 'string', minLength: 1, maxLength: 500 }, + }, + ['date', 'note'], + ), + ), + segmentParamSchema: () => + required( + objectSchema( + { + filters: { type: 'array', items: { type: 'object', additionalProperties: true } }, + match: { type: 'string', enum: ['all', 'any'] }, + dateRange: stringSchema(), + action: objectSchema({ type: stringSchema(), value: stringSchema() }), + }, + [], + ), + ), + reportSchema: () => + required( + objectSchema( + { + websiteId: { type: 'string', format: 'uuid' }, + type: stringSchema(), + name: { type: 'string', maxLength: 200 }, + description: { type: 'string', maxLength: 500 }, + parameters: { type: 'object', additionalProperties: true }, + }, + ['websiteId', 'type', 'name', 'parameters'], + ), + ), + reportResultSchema: () => + required( + objectSchema( + { + websiteId: { type: 'string', format: 'uuid' }, + filters: { type: 'object', additionalProperties: true }, + type: stringSchema(), + parameters: { type: 'object', additionalProperties: true }, + }, + ['websiteId', 'filters', 'type', 'parameters'], + ), + ), +}; + +const knownFragments: Record = { + dateRangeParams: objectSchema( + { + startAt: numberSchema(), + endAt: numberSchema(), + startDate: { type: 'string', format: 'date-time' }, + endDate: { type: 'string', format: 'date-time' }, + timezone: stringSchema(), + unit: stringSchema(), + compare: { type: 'string', enum: ['prev', 'yoy'] }, + }, + [], + ), + filterParams: objectSchema( + { + ...Object.fromEntries( + [ + 'path', + 'referrer', + 'title', + 'query', + 'os', + 'browser', + 'device', + 'country', + 'region', + 'city', + 'tag', + 'hostname', + 'distinctId', + 'language', + 'event', + 'utmSource', + 'utmMedium', + 'utmCampaign', + 'utmContent', + 'utmTerm', + 'excludeBounce', + ].map(name => [name, stringSchema()]), + ), + segment: { type: 'string', format: 'uuid' }, + cohort: { type: 'string', format: 'uuid' }, + eventType: { type: 'integer', minimum: 1 }, + match: { type: 'string', enum: ['all', 'any'] }, + }, + [], + ), + searchParams: objectSchema({ search: stringSchema() }, []), + replayParams: objectSchema({ minDuration: { type: 'integer', minimum: 0 } }, []), + pagingParams: objectSchema( + { + page: { type: 'integer', minimum: 1 }, + pageSize: { type: 'integer', minimum: 1 }, + maxResults: { type: 'integer', minimum: 1 }, + }, + [], + ), + sortingParams: objectSchema( + { + orderBy: stringSchema(), + sortDescending: { type: 'string', enum: ['true', 'false'] }, + }, + [], + ), +}; + +function getPropertyName(node: ts.PropertyName | undefined, source: ts.SourceFile) { + if (!node) { + return null; + } + + if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node)) { + return node.text; + } + + return node.getText(source).replace(/^['"]|['"]$/g, ''); +} + +function getLiteralValue(expression: ts.Expression): string | number | boolean | null | undefined { + if (ts.isStringLiteral(expression)) { + return expression.text; + } + + if (ts.isNumericLiteral(expression)) { + return Number(expression.text); + } + + if (expression.kind === ts.SyntaxKind.TrueKeyword) { + return true; + } + + if (expression.kind === ts.SyntaxKind.FalseKeyword) { + return false; + } + + if (expression.kind === ts.SyntaxKind.NullKeyword) { + return null; + } + + return undefined; +} + +function mergeObjectSchemas(target: Schema, source: Schema) { + const targetProperties = (target.properties ?? {}) as Record; + const sourceProperties = (source.properties ?? {}) as Record; + const requiredProperties = new Set([ + ...((target.required ?? []) as string[]), + ...((source.required ?? []) as string[]), + ]); + + target.type = 'object'; + target.properties = { ...targetProperties, ...sourceProperties }; + + if (requiredProperties.size) { + target.required = [...requiredProperties]; + } +} + +function inferObjectLiteral( + expression: ts.ObjectLiteralExpression, + source: ts.SourceFile, + declarations: Map, + seen: Set, +): InferredSchema { + const properties: Record = {}; + const requiredProperties = new Set(); + + expression.properties.forEach(property => { + if (ts.isSpreadAssignment(property)) { + const inferred = inferExpression(property.expression, source, declarations, seen); + Object.assign(properties, (inferred.schema.properties ?? {}) as Record); + ((inferred.schema.required ?? []) as string[]).forEach(name => { + requiredProperties.add(name); + }); + return; + } + + if (ts.isPropertyAssignment(property)) { + const name = getPropertyName(property.name, source); + + if (!name) { + return; + } + + const inferred = inferExpression(property.initializer, source, declarations, seen); + properties[name] = inferred.schema; + + if (!inferred.optional) { + requiredProperties.add(name); + } + return; + } + + if (ts.isShorthandPropertyAssignment(property)) { + const name = property.name.text; + const inferred = inferExpression(property.name, source, declarations, seen); + properties[name] = inferred.schema; + + if (!inferred.optional) { + requiredProperties.add(name); + } + } + }); + + return required(objectSchema(properties, [...requiredProperties])); +} + +function applyConstraint(schema: Schema, method: string, argument?: ts.Expression) { + const value = argument ? getLiteralValue(argument) : undefined; + + if (method === 'int') { + schema.type = 'integer'; + } else if (method === 'positive') { + schema.exclusiveMinimum = 0; + } else if (method === 'nonnegative') { + schema.minimum = 0; + } else if (method === 'min' && typeof value === 'number') { + const numericValue = value; + + if (schema.type === 'string') schema.minLength = numericValue; + else if (schema.type === 'array') schema.minItems = numericValue; + else schema.minimum = numericValue; + } else if (method === 'max' && typeof value === 'number') { + const numericValue = value; + + if (schema.type === 'string') schema.maxLength = numericValue; + else if (schema.type === 'array') schema.maxItems = numericValue; + else schema.maximum = numericValue; + } else if (method === 'length' && typeof value === 'number') { + const numericValue = value; + + if (schema.type === 'array') { + schema.minItems = numericValue; + schema.maxItems = numericValue; + } else { + schema.minLength = numericValue; + schema.maxLength = numericValue; + } + } +} + +function inferCallExpression( + expression: ts.CallExpression, + source: ts.SourceFile, + declarations: Map, + seen: Set, +): InferredSchema { + const callee = expression.expression; + const method = ts.isPropertyAccessExpression(callee) ? callee.name.text : callee.getText(source); + const base = ts.isPropertyAccessExpression(callee) ? callee.expression : undefined; + + if (method === 'withDateRange') { + const schema = structuredClone(knownFragments.dateRangeParams); + + if (expression.arguments[0]) { + mergeObjectSchemas( + schema, + inferExpression(expression.arguments[0], source, declarations, seen).schema, + ); + } + + return required(schema); + } + + if (['optional', 'nullish', 'default', 'catch'].includes(method) && base) { + const inferred = inferExpression(base, source, declarations, seen); + + if (method === 'nullish') { + inferred.schema = { anyOf: [inferred.schema, { type: 'null' }] }; + } + + inferred.optional = true; + return inferred; + } + + if (method === 'nullable' && base) { + const inferred = inferExpression(base, source, declarations, seen); + inferred.schema = { anyOf: [inferred.schema, { type: 'null' }] }; + return inferred; + } + + if (method === 'or' && base && expression.arguments[0]) { + const left = inferExpression(base, source, declarations, seen); + const right = inferExpression(expression.arguments[0], source, declarations, seen); + return { + schema: { anyOf: [left.schema, right.schema] }, + optional: left.optional && right.optional, + }; + } + + if ( + [ + 'refine', + 'superRefine', + 'transform', + 'pipe', + 'strict', + 'passthrough', + 'strip', + 'describe', + 'meta', + 'brand', + 'readonly', + ].includes(method) && + base + ) { + return inferExpression(base, source, declarations, seen); + } + + if (['min', 'max', 'length', 'int', 'positive', 'nonnegative'].includes(method) && base) { + const inferred = inferExpression(base, source, declarations, seen); + applyConstraint(inferred.schema, method, expression.arguments[0]); + return inferred; + } + + if (method === 'partial' && base) { + const inferred = inferExpression(base, source, declarations, seen); + delete inferred.schema.required; + return inferred; + } + + if (method === 'array' && expression.arguments[0]) { + return required({ + type: 'array', + items: inferExpression(expression.arguments[0], source, declarations, seen).schema, + }); + } + + if ( + method === 'object' && + expression.arguments[0] && + ts.isObjectLiteralExpression(expression.arguments[0]) + ) { + return inferObjectLiteral(expression.arguments[0], source, declarations, seen); + } + + if (method === 'record') { + const valueExpression = expression.arguments.at(-1); + return required({ + type: 'object', + additionalProperties: valueExpression + ? inferExpression(valueExpression, source, declarations, seen).schema + : true, + }); + } + + if (['union', 'discriminatedUnion'].includes(method)) { + const variantsExpression = expression.arguments[method === 'union' ? 0 : 1]; + + if (variantsExpression && ts.isArrayLiteralExpression(variantsExpression)) { + return required({ + anyOf: variantsExpression.elements.map( + element => inferExpression(element as ts.Expression, source, declarations, seen).schema, + ), + }); + } + } + + if (method === 'intersection' && expression.arguments.length >= 2) { + return required({ + allOf: expression.arguments.map( + argument => inferExpression(argument, source, declarations, seen).schema, + ), + }); + } + + if ( + method === 'enum' && + expression.arguments[0] && + ts.isArrayLiteralExpression(expression.arguments[0]) + ) { + return required({ + type: 'string', + enum: expression.arguments[0].elements + .map(element => getLiteralValue(element as ts.Expression)) + .filter((value): value is string => typeof value === 'string'), + }); + } + + if (method === 'literal' && expression.arguments[0]) { + const value = getLiteralValue(expression.arguments[0]); + return value === undefined ? required(unknownSchema()) : required({ const: value }); + } + + if ( + method === 'tuple' && + expression.arguments[0] && + ts.isArrayLiteralExpression(expression.arguments[0]) + ) { + const prefixItems = expression.arguments[0].elements.map( + element => inferExpression(element as ts.Expression, source, declarations, seen).schema, + ); + return required({ + type: 'array', + prefixItems, + minItems: prefixItems.length, + maxItems: prefixItems.length, + }); + } + + if (['string', 'email', 'url'].includes(method)) { + return required({ type: 'string', ...(method !== 'string' ? { format: method } : {}) }); + } + + if (['uuid', 'guid'].includes(method)) { + return required({ type: 'string', format: 'uuid' }); + } + + if (method === 'date') { + return required({ type: 'string', format: 'date-time' }); + } + + if (['number', 'float32', 'float64'].includes(method)) { + return required(numberSchema()); + } + + if (['int', 'int32', 'int64'].includes(method) && base?.getText(source).startsWith('z')) { + return required({ type: 'integer' }); + } + + if (method === 'boolean') { + return required(booleanSchema()); + } + + if (['any', 'unknown', 'undefined', 'void', 'never'].includes(method)) { + return required(unknownSchema()); + } + + if (ts.isIdentifier(callee) && knownSchemas[callee.text]) { + return knownSchemas[callee.text](); + } + + return required(unknownSchema()); +} + +function inferExpression( + expression: ts.Expression, + source: ts.SourceFile, + declarations: Map, + seen = new Set(), +): InferredSchema { + if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression)) { + return inferExpression(expression.expression, source, declarations, seen); + } + + if (ts.isIdentifier(expression)) { + const name = expression.text; + + if (knownFragments[name]) { + return required(structuredClone(knownFragments[name])); + } + + if (knownSchemas[name]) { + return knownSchemas[name](); + } + + const declaration = declarations.get(name); + + if (declaration && !seen.has(name)) { + const nextSeen = new Set(seen); + nextSeen.add(name); + return inferExpression(declaration, source, declarations, nextSeen); + } + + return required(unknownSchema()); + } + + if (ts.isObjectLiteralExpression(expression)) { + return inferObjectLiteral(expression, source, declarations, seen); + } + + if (ts.isArrayLiteralExpression(expression)) { + const variants = expression.elements.map( + element => inferExpression(element as ts.Expression, source, declarations, seen).schema, + ); + return required({ + type: 'array', + items: variants.length === 1 ? variants[0] : { anyOf: variants }, + }); + } + + if (ts.isCallExpression(expression)) { + return inferCallExpression(expression, source, declarations, seen); + } + + const literal = getLiteralValue(expression); + + if (literal !== undefined) { + return required({ const: literal }); + } + + return required(unknownSchema()); +} + +function collectDeclarations(node: ts.Node, declarations: Map) { + if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) { + declarations.set(node.name.text, node.initializer); + } + + ts.forEachChild(node, child => collectDeclarations(child, declarations)); +} + +function findHandler(source: ts.SourceFile, method: ApiHttpMethod): ts.Node | undefined { + const methodName = method.toUpperCase(); + + for (const statement of source.statements) { + if (ts.isFunctionDeclaration(statement) && statement.name?.text === methodName) { + return statement; + } + + if (ts.isVariableStatement(statement)) { + const declaration = statement.declarationList.declarations.find( + item => ts.isIdentifier(item.name) && item.name.text === methodName, + ); + + if (declaration?.initializer) { + return declaration.initializer; + } + } + } + + return undefined; +} + +function getNumericStatus(options: ts.Expression | undefined, source: ts.SourceFile) { + if (!options || !ts.isObjectLiteralExpression(options)) { + return null; + } + + const status = options.properties.find( + property => + ts.isPropertyAssignment(property) && getPropertyName(property.name, source) === 'status', + ); + + if (!status || !ts.isPropertyAssignment(status)) { + return null; + } + + const value = getLiteralValue(status.initializer); + return typeof value === 'string' ? Number(value) : typeof value === 'number' ? value : null; +} + +export function analyzeSourceOperation( + source: ts.SourceFile, + method: ApiHttpMethod, +): SourceOperationAnalysis { + const handler = findHandler(source, method); + + if (!handler) { + return { + auth: 'bearer', + hasRequestSchema: false, + responseStatuses: [200], + responseMediaType: 'application/json', + returnsOk: false, + }; + } + + const declarations = new Map(); + source.statements.forEach(statement => { + if (ts.isVariableStatement(statement)) { + statement.declarationList.declarations.forEach(declaration => { + if (ts.isIdentifier(declaration.name) && declaration.initializer) { + declarations.set(declaration.name.text, declaration.initializer); + } + }); + } + }); + collectDeclarations(handler, declarations); + + let parseRequestCall: ts.CallExpression | undefined; + let hasShareAwarePermission = false; + let returnsOk = false; + let responseMediaType = 'application/json'; + const responseStatuses = new Set(); + + const visit = (node: ts.Node) => { + if (ts.isCallExpression(node)) { + const calleeText = node.expression.getText(source); + const name = ts.isIdentifier(node.expression) + ? node.expression.text + : ts.isPropertyAccessExpression(node.expression) + ? node.expression.name.text + : calleeText; + + if (name === 'parseRequest' && !parseRequestCall) { + parseRequestCall = node; + } + + if (/^canView/.test(name)) { + hasShareAwarePermission = true; + } + + const mappedStatus = RESPONSE_STATUSES[name]; + + if (mappedStatus) { + responseStatuses.add(mappedStatus); + returnsOk ||= name === 'ok'; + } + + if (calleeText === 'Response.json') { + responseStatuses.add(getNumericStatus(node.arguments[1], source) ?? 200); + } + } + + if (ts.isNewExpression(node) && node.expression.getText(source) === 'Response') { + responseStatuses.add(getNumericStatus(node.arguments?.[1], source) ?? 200); + responseMediaType = handler.getText(source).includes('text/javascript') + ? 'text/javascript' + : 'text/plain'; + } + + ts.forEachChild(node, visit); + }; + + visit(handler); + + const schemaArgument = parseRequestCall?.arguments[1]; + const hasRequestSchema = Boolean( + schemaArgument && schemaArgument.kind !== ts.SyntaxKind.NullKeyword, + ); + const skipAuth = + parseRequestCall?.arguments[2]?.getText(source).includes('skipAuth: true') ?? false; + const auth: ApiAuth = + !parseRequestCall || skipAuth ? 'none' : hasShareAwarePermission ? 'bearer-or-share' : 'bearer'; + + if (hasRequestSchema) { + responseStatuses.add(400); + } + + if (auth !== 'none') { + responseStatuses.add(401); + } + + if (![...responseStatuses].some(status => status >= 200 && status < 400)) { + responseStatuses.add(200); + } + + return { + auth, + hasRequestSchema, + requestSchema: schemaArgument + ? inferExpression(schemaArgument, source, declarations).schema + : undefined, + responseStatuses: [...responseStatuses].sort((left, right) => left - right), + responseMediaType, + returnsOk, + }; +}