{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/mailcheer-com/json-schema/mailcheer-com-campaign-stats-schema.json",
  "title": "CampaignStats",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/mailcheer-com-openapi.json#/components/schemas/CampaignStats",
  "type": "object",
  "properties": {
    "campaign": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "subject": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "enum": [
            "draft",
            "scheduled",
            "sending",
            "testing",
            "sent",
            "archived"
          ]
        },
        "kind": {
          "type": "string"
        },
        "fromName": {
          "type": "string"
        },
        "fromEmail": {
          "type": "string"
        },
        "sentAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "scheduledAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    },
    "counts": {
      "type": "object",
      "properties": {
        "recipients": {
          "type": "integer"
        },
        "delivered": {
          "type": "integer"
        },
        "opened": {
          "type": "integer"
        },
        "clicked": {
          "type": "integer"
        },
        "humanOpened": {
          "type": "integer",
          "description": "Messages opened (or clicked) at least once by a person."
        },
        "humanClicked": {
          "type": "integer",
          "description": "Messages clicked at least once by a person."
        },
        "bounced": {
          "type": "integer"
        },
        "complained": {
          "type": "integer"
        },
        "unsubscribed": {
          "type": "integer",
          "description": "People who unsubscribed through this campaign's link (same definition as `recipients?status=unsubscribed`). An unsubscribe made through the API or in the app counts on no campaign."
        },
        "untracked": {
          "type": "integer",
          "description": "Delivered messages that went out without an open-tracking pixel. Open rates are computed on the others; with none left, they are `null`."
        }
      },
      "description": "A bot is an open or a click within two minutes of delivery (security gateways visit every link as the message arrives; privacy relays preload images), or one from a robot that declares itself in its user agent or comes from an address range its operator publishes (Google, Bing). Privacy relays (Apple Mail, Gmail, Yahoo) are not bots in themselves."
    },
    "rates": {
      "type": "object",
      "description": "Shares between 0 and 1; `null` as long as the denominator is empty.",
      "properties": {
        "delivered": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1
        },
        "opened": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1
        },
        "clicked": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1
        },
        "humanOpened": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1,
          "description": "`opened` without bots, on delivered messages."
        },
        "humanClicked": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1,
          "description": "`clicked` without bots, on delivered messages."
        },
        "bounced": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1
        }
      }
    },
    "bots": {
      "type": "object",
      "description": "Opens and clicks set aside as bots, counted as events (a gateway visiting three links counts three clicks), and why.",
      "properties": {
        "opened": {
          "type": "integer",
          "description": "Bot opens."
        },
        "clicked": {
          "type": "integer",
          "description": "Bot clicks."
        },
        "delay": {
          "type": "integer",
          "description": "Within two minutes of delivery."
        },
        "scanner": {
          "type": "integer",
          "description": "A robot that declares itself, or an address its operator publishes."
        }
      }
    },
    "timeline": {
      "type": "array",
      "description": "Eight six-hour windows from the send, `+0h` to `+42h`. Empty if the campaign has not gone out.",
      "items": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "opened": {
            "type": "integer"
          },
          "clicked": {
            "type": "integer"
          },
          "humanOpened": {
            "type": "integer",
            "description": "Opens by people in the window."
          },
          "humanClicked": {
            "type": "integer",
            "description": "Clicks by people in the window."
          }
        }
      }
    },
    "audience": {
      "type": "object",
      "properties": {
        "total": {
          "type": "integer",
          "description": "Opens by people whose device is known (bot opens excluded)."
        },
        "proxiedShare": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1,
          "description": "Share of opens coming from a privacy relay (Apple Mail, Gmail): received, not necessarily read."
        },
        "device": {
          "type": "array",
          "description": "Five rows at most, from the most to the least frequent.",
          "items": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string"
              },
              "count": {
                "type": "integer"
              },
              "share": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            }
          }
        },
        "os": {
          "type": "array",
          "description": "Five rows at most, from the most to the least frequent.",
          "items": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string"
              },
              "count": {
                "type": "integer"
              },
              "share": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            }
          }
        },
        "client": {
          "type": "array",
          "description": "Five rows at most, from the most to the least frequent.",
          "items": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string"
              },
              "count": {
                "type": "integer"
              },
              "share": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            }
          }
        }
      }
    },
    "links": {
      "type": "array",
      "description": "From most to least clicked, by people (bot clicks excluded).",
      "items": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "clicks": {
            "type": "integer"
          }
        }
      }
    },
    "html": {
      "type": "string",
      "description": "The HTML as rendered at send time; empty string as long as it does not exist."
    }
  }
}