{
  "openapi": "3.1.0",
  "info": {
    "title": "Pairfully API",
    "version": "1.0.0",
    "description": "Read your Pairfully data: sites, weekly reports, exit reasons, friction pages, sessions, hot visitors, leads and alert rules. Authenticate with an API key (Settings \u2192 API, Scale and Agency plans) as a Bearer token. Rate limits: 60 requests a minute and 10,000 a day per key; a 429 carries Retry-After. Response shapes in v1 are stable: fields may be added, never renamed or removed.",
    "contact": {
      "url": "https://pairfully.com/docs/api"
    }
  },
  "servers": [
    {
      "url": "https://api.pairfully.com"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/sites": {
      "get": {
        "operationId": "listSites",
        "summary": "List sites",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Site"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/sites/{siteId}": {
      "get": {
        "operationId": "getSite",
        "summary": "Get a site",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Site"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/sites/{siteId}/overview": {
      "get": {
        "operationId": "getOverview",
        "summary": "Overview",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          },
          {
            "name": "range",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "custom"
              ],
              "default": "7d"
            },
            "description": "Window. custom needs from and to."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "First day (UTC), custom range only."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Last day (UTC, inclusive), custom range only."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Overview"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "description": "Totals, the previous period and deltas, exit reasons with share, pages and estimated impact, friction pages, the intent funnel and the unclear count."
      }
    },
    "/v1/sites/{siteId}/compare": {
      "get": {
        "operationId": "comparePeriods",
        "summary": "Compare periods",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          },
          {
            "name": "range",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d"
              ],
              "default": "7d"
            },
            "description": "Window compared with the one before it."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Compare"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "description": "This period versus the previous one, with the biggest movers in exit reasons and friction pages."
      }
    },
    "/v1/sites/{siteId}/reports": {
      "get": {
        "operationId": "listReports",
        "summary": "List weekly reports",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 26,
              "default": 4
            },
            "description": "Newest first."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Report"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/sites/{siteId}/reports/latest": {
      "get": {
        "operationId": "getLatestReport",
        "summary": "Latest weekly report",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Report"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/sites/{siteId}/reports/{reportId}": {
      "get": {
        "operationId": "getReport",
        "summary": "Get a weekly report",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          },
          {
            "name": "reportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Report id."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Report"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/sites/{siteId}/sessions": {
      "get": {
        "operationId": "listSessions",
        "summary": "List sessions",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "YYYY-MM-DD or ISO timestamp."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "YYYY-MM-DD (inclusive) or ISO timestamp."
          },
          {
            "name": "exitReason",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Reason key."
          },
          {
            "name": "minIntent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 4
            },
            "description": "Lowest intent level."
          },
          {
            "name": "converted",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "true or false."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "nextCursor from the previous page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Page size."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionListItem"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "description": "Newest first."
      }
    },
    "/v1/sites/{siteId}/sessions/{sessionId}": {
      "get": {
        "operationId": "getSession",
        "summary": "Get a session",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          },
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Session id, or the id carried by a hot-visitor alert."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "description": "The path, Pairfully's verdict and the reasons, in plain English too."
      }
    },
    "/v1/sites/{siteId}/hot-visitors": {
      "get": {
        "operationId": "listHotVisitors",
        "summary": "Recent hot visitors",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Default: 24 hours ago. At most 30 days back."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/HotVisitor"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "description": "Recent hot-visitor alerts, newest first, up to 100."
      }
    },
    "/v1/sites/{siteId}/leads": {
      "get": {
        "operationId": "listLeads",
        "summary": "List leads",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "nextCursor from the previous page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Page size."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Lead"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "description": "Scored form submissions, newest first, with contact details already stripped."
      }
    },
    "/v1/sites/{siteId}/alert-rules": {
      "get": {
        "operationId": "listAlertRules",
        "summary": "List alert rules",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AlertRule"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createAlertRule",
        "summary": "Create an email alert rule",
        "description": "Needs the alerts:write scope. Email only for now. If a rule for that address exists, its minIntent is updated and it is re-enabled (200).",
        "parameters": [
          {
            "$ref": "#/components/parameters/siteId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "minIntent": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 4,
                    "default": 3
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertRule"
                }
              }
            }
          },
          "200": {
            "description": "Existing rule updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertRule"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "summary": "This document",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "pf_sk_\u2026",
        "description": "An API key, pf_sk_ followed by 32 characters."
      }
    },
    "parameters": {
      "siteId": {
        "name": "siteId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Site id from GET /v1/sites. Must belong to the key's organisation."
      }
    },
    "responses": {
      "BadRequest": {
        "description": "invalid_request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "unauthorized: missing, invalid, revoked or expired key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "plan_required (the organisation is not on Scale or Agency) or insufficient_scope",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "not_found, including sites outside the key's organisation",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "rate_limited",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds to wait."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "unauthorized",
                  "insufficient_scope",
                  "plan_required",
                  "forbidden",
                  "not_found",
                  "invalid_request",
                  "conflict",
                  "rate_limited",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Site": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "ecommerce",
              "saas",
              "services",
              "leadgen",
              "other"
            ]
          },
          "timezone": {
            "type": "string"
          },
          "averageOrderValue": {
            "type": [
              "integer",
              "null"
            ]
          },
          "installed": {
            "type": "boolean"
          },
          "lastEventAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "domain",
          "type",
          "timezone",
          "averageOrderValue",
          "installed",
          "lastEventAt",
          "createdAt"
        ]
      },
      "Window": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "from",
          "to"
        ]
      },
      "Impact": {
        "type": "object",
        "properties": {
          "sessionsPerWeek": {
            "type": "integer"
          },
          "revenue": {
            "type": [
              "number",
              "null"
            ]
          },
          "currency": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "USD",
              null
            ]
          }
        },
        "required": [
          "sessionsPerWeek",
          "revenue",
          "currency"
        ],
        "description": "Estimated weekly impact: sessions a reason costs per week, and revenue if a fix won back about 1 in 10 of them (null without an average order value). An estimate."
      },
      "ExitReason": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "Reason key, e.g. shipping_or_delivery_info, price_shock, form_or_checkout_friction, trust_or_credibility, comparing_options, wrong_audience, just_browsing, technical_error, or unclear (always last)."
          },
          "label": {
            "type": "string"
          },
          "sessions": {
            "type": "integer"
          },
          "share": {
            "type": "number",
            "description": "Fraction of serious visitors who didn't buy."
          },
          "pages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "estimatedImpact": {
            "$ref": "#/components/schemas/Impact"
          }
        },
        "required": [
          "reason",
          "label",
          "sessions",
          "share",
          "pages",
          "estimatedImpact"
        ]
      },
      "FrictionPage": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "page": {
            "type": "string"
          },
          "sessions": {
            "type": "integer"
          },
          "share": {
            "type": "number"
          },
          "topReason": {
            "type": "string"
          },
          "topReasonLabel": {
            "type": "string"
          }
        },
        "required": [
          "path",
          "page",
          "sessions",
          "share",
          "topReason",
          "topReasonLabel"
        ]
      },
      "Totals": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": "integer"
          },
          "visitors": {
            "type": "integer"
          },
          "conversions": {
            "type": "integer"
          },
          "conversionRate": {
            "type": "number"
          },
          "seriousNonConverted": {
            "type": "integer"
          }
        },
        "required": [
          "sessions",
          "visitors",
          "conversions",
          "conversionRate"
        ]
      },
      "Deltas": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": [
              "number",
              "null"
            ]
          },
          "visitors": {
            "type": [
              "number",
              "null"
            ]
          },
          "conversions": {
            "type": [
              "number",
              "null"
            ]
          },
          "conversionRate": {
            "type": "number",
            "description": "Absolute change in conversion rate."
          }
        },
        "required": [
          "sessions",
          "visitors",
          "conversions",
          "conversionRate"
        ],
        "description": "Relative change (0.12 = +12%; null when the previous period was 0), except conversionRate, which is absolute."
      },
      "Overview": {
        "type": "object",
        "properties": {
          "siteId": {
            "type": "string"
          },
          "range": {
            "type": "string",
            "enum": [
              "7d",
              "30d",
              "custom"
            ]
          },
          "window": {
            "$ref": "#/components/schemas/Window"
          },
          "previousWindow": {
            "$ref": "#/components/schemas/Window"
          },
          "totals": {
            "$ref": "#/components/schemas/Totals"
          },
          "previousTotals": {
            "$ref": "#/components/schemas/Totals"
          },
          "deltas": {
            "$ref": "#/components/schemas/Deltas"
          },
          "exitReasons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExitReason"
            }
          },
          "frictionPages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FrictionPage"
            }
          },
          "intentFunnel": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "level": {
                  "type": "integer"
                },
                "label": {
                  "type": "string"
                },
                "sessions": {
                  "type": "integer"
                }
              },
              "required": [
                "level",
                "label",
                "sessions"
              ]
            }
          },
          "unclear": {
            "type": "object",
            "properties": {
              "sessions": {
                "type": "integer"
              },
              "share": {
                "type": "number"
              }
            },
            "required": [
              "sessions",
              "share"
            ]
          },
          "unratedSessions": {
            "type": "integer"
          },
          "sampled": {
            "type": "boolean"
          }
        },
        "required": [
          "siteId",
          "range",
          "window",
          "previousWindow",
          "totals",
          "previousTotals",
          "deltas",
          "exitReasons",
          "frictionPages",
          "intentFunnel",
          "unclear",
          "unratedSessions",
          "sampled"
        ]
      },
      "Fix": {
        "type": "object",
        "properties": {
          "rank": {
            "type": "integer"
          },
          "reason": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "action": {
            "type": "string"
          },
          "share": {
            "type": "number"
          },
          "pages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "estimatedImpact": {
            "$ref": "#/components/schemas/Impact"
          }
        },
        "required": [
          "rank",
          "reason",
          "label",
          "title",
          "action",
          "share",
          "pages",
          "estimatedImpact"
        ]
      },
      "Report": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "siteId": {
            "type": "string"
          },
          "weekStart": {
            "type": "string",
            "format": "date-time"
          },
          "weekEnd": {
            "type": "string",
            "format": "date-time"
          },
          "weekLabel": {
            "type": "string"
          },
          "sentAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lede": {
            "type": "string"
          },
          "reasons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExitReason"
            }
          },
          "fixes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Fix"
            }
          },
          "stats": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "value": {
                  "type": "number"
                },
                "delta": {
                  "type": [
                    "number",
                    "null"
                  ]
                }
              },
              "required": [
                "key",
                "label",
                "value",
                "delta"
              ]
            }
          },
          "frictionPages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FrictionPage"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "referrer": {
                  "type": "string"
                },
                "sessions": {
                  "type": "integer"
                },
                "conversions": {
                  "type": "integer"
                },
                "conversionRate": {
                  "type": "number"
                }
              },
              "required": [
                "referrer",
                "sessions",
                "conversions",
                "conversionRate"
              ]
            }
          },
          "unrated": {
            "type": "integer"
          },
          "sampled": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "siteId",
          "weekStart",
          "weekEnd",
          "weekLabel",
          "sentAt",
          "lede",
          "reasons",
          "fixes",
          "stats",
          "frictionPages",
          "sources",
          "unrated",
          "sampled"
        ]
      },
      "Verdict": {
        "type": "object",
        "properties": {
          "exitReason": {
            "type": "string"
          },
          "exitReasonLabel": {
            "type": "string"
          },
          "intentLevel": {
            "type": "integer",
            "minimum": 0,
            "maximum": 4
          },
          "intentLabel": {
            "type": "string"
          },
          "visitorType": {
            "type": "string"
          },
          "frictionPage": {
            "type": [
              "string",
              "null"
            ]
          },
          "clear": {
            "type": "boolean",
            "description": "False when Pairfully wasn't confident; such visits count as unclear."
          }
        },
        "required": [
          "exitReason",
          "exitReasonLabel",
          "intentLevel",
          "intentLabel",
          "visitorType",
          "frictionPage",
          "clear"
        ]
      },
      "SessionListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "durationSeconds": {
            "type": "integer"
          },
          "pages": {
            "type": "integer"
          },
          "referrer": {
            "type": "string"
          },
          "device": {
            "type": "string"
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "converted": {
            "type": "boolean"
          },
          "verdict": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Verdict"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "startedAt",
          "durationSeconds",
          "pages",
          "referrer",
          "device",
          "country",
          "converted",
          "verdict"
        ]
      },
      "PathStep": {
        "type": "object",
        "properties": {
          "page": {
            "type": "string"
          },
          "seconds": {
            "type": "integer"
          },
          "scroll": {
            "type": [
              "number",
              "null"
            ]
          },
          "clicks": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "formErrors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "rageClicks": {
            "type": "integer"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exit": {
            "type": "boolean"
          }
        },
        "required": [
          "page",
          "seconds",
          "scroll",
          "clicks",
          "formErrors",
          "rageClicks",
          "errors",
          "exit"
        ]
      },
      "Session": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SessionListItem"
          },
          {
            "type": "object",
            "properties": {
              "path": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PathStep"
                }
              },
              "story": {
                "type": "string"
              },
              "reasons": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "summary": {
                        "type": "string"
                      },
                      "confused": {
                        "type": "boolean"
                      },
                      "hitDeadEnd": {
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "summary",
                      "confused",
                      "hitDeadEnd"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "path",
              "story",
              "reasons"
            ]
          }
        ]
      },
      "HotVisitor": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "headline": {
            "type": "string"
          },
          "page": {
            "type": "string"
          },
          "intentLevel": {
            "type": [
              "integer",
              "null"
            ]
          },
          "intentLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "wantsHuman": {
            "type": "boolean"
          },
          "device": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "sessionId": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "at",
          "headline",
          "page",
          "intentLevel",
          "intentLabel",
          "wantsHuman",
          "device",
          "country",
          "sessionId"
        ]
      },
      "Level": {
        "type": "object",
        "properties": {
          "level": {
            "type": "integer",
            "minimum": 0,
            "maximum": 4
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "level",
          "label"
        ]
      },
      "Lead": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "fields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Submitted fields with contact details removed."
          },
          "fit": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Level"
              },
              {
                "type": "null"
              }
            ]
          },
          "intent": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Level"
              },
              {
                "type": "null"
              }
            ]
          },
          "route": {
            "type": [
              "string",
              "null"
            ]
          },
          "likelySpam": {
            "type": "boolean"
          },
          "sessionId": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "createdAt",
          "fields",
          "fit",
          "intent",
          "route",
          "likelySpam",
          "sessionId"
        ]
      },
      "AlertRule": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "channel": {
            "type": "string",
            "enum": [
              "EMAIL",
              "SLACK",
              "WHATSAPP"
            ]
          },
          "target": {
            "type": "string"
          },
          "minIntent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 4
          },
          "enabled": {
            "type": "boolean"
          },
          "delivering": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "channel",
          "target",
          "minIntent",
          "enabled",
          "delivering",
          "createdAt"
        ]
      },
      "CompareRow": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": "integer"
          },
          "share": {
            "type": "number"
          }
        },
        "required": [
          "sessions",
          "share"
        ]
      },
      "CompareReason": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "current": {
            "$ref": "#/components/schemas/CompareRow"
          },
          "previous": {
            "$ref": "#/components/schemas/CompareRow"
          },
          "shareChange": {
            "type": "number"
          },
          "sessionsChange": {
            "type": "integer"
          }
        },
        "required": [
          "reason",
          "label",
          "current",
          "previous",
          "shareChange",
          "sessionsChange"
        ]
      },
      "ComparePage": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "page": {
            "type": "string"
          },
          "current": {
            "$ref": "#/components/schemas/CompareRow"
          },
          "previous": {
            "$ref": "#/components/schemas/CompareRow"
          },
          "shareChange": {
            "type": "number"
          },
          "sessionsChange": {
            "type": "integer"
          }
        },
        "required": [
          "path",
          "page",
          "current",
          "previous",
          "shareChange",
          "sessionsChange"
        ]
      },
      "Compare": {
        "type": "object",
        "properties": {
          "siteId": {
            "type": "string"
          },
          "range": {
            "type": "string",
            "enum": [
              "7d",
              "30d"
            ]
          },
          "current": {
            "type": "object",
            "properties": {
              "window": {
                "$ref": "#/components/schemas/Window"
              },
              "totals": {
                "$ref": "#/components/schemas/Totals"
              }
            },
            "required": [
              "window",
              "totals"
            ]
          },
          "previous": {
            "type": "object",
            "properties": {
              "window": {
                "$ref": "#/components/schemas/Window"
              },
              "totals": {
                "$ref": "#/components/schemas/Totals"
              }
            },
            "required": [
              "window",
              "totals"
            ]
          },
          "deltas": {
            "$ref": "#/components/schemas/Deltas"
          },
          "exitReasons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompareReason"
            }
          },
          "frictionPages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComparePage"
            }
          },
          "biggestMovers": {
            "type": "object",
            "properties": {
              "exitReasons": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CompareReason"
                }
              },
              "frictionPages": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ComparePage"
                }
              }
            },
            "required": [
              "exitReasons",
              "frictionPages"
            ]
          }
        },
        "required": [
          "siteId",
          "range",
          "current",
          "previous",
          "deltas",
          "exitReasons",
          "frictionPages",
          "biggestMovers"
        ]
      }
    }
  }
}
