{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/medianfi-com/json-schema/medianfi-com-therapist-metrics-envelope-response-schema.json",
  "title": "TherapistMetricsEnvelopeResponse",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/medianfi-com-openapi.json#/components/schemas/TherapistMetricsEnvelopeResponse",
  "type": "object",
  "required": [
    "success",
    "data"
  ],
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "data": {
      "type": "object",
      "required": [
        "packet",
        "therapists",
        "channels",
        "cac",
        "serviceValue",
        "retention",
        "ltvToCac"
      ],
      "properties": {
        "packet": {
          "type": [
            "object",
            "null"
          ],
          "required": [
            "id",
            "formatVersion",
            "reportStart",
            "cutoff",
            "historyStart",
            "historyComplete",
            "currency",
            "timezone",
            "approvedAt",
            "importedAt",
            "nextPacketDueBy",
            "stale",
            "definitions",
            "sources"
          ],
          "properties": {
            "id": {
              "type": "string",
              "format": "uuid"
            },
            "formatVersion": {
              "type": "string"
            },
            "reportStart": {
              "type": "string",
              "format": "date"
            },
            "cutoff": {
              "type": "string",
              "format": "date"
            },
            "historyStart": {
              "type": "string",
              "format": "date"
            },
            "historyComplete": {
              "type": "boolean",
              "description": "False means LTV and LTGP are observed since historyStart, not lifetime"
            },
            "currency": {
              "type": "string"
            },
            "timezone": {
              "type": "string"
            },
            "approvedAt": {
              "type": "string",
              "format": "date-time"
            },
            "importedAt": {
              "type": "string",
              "format": "date-time"
            },
            "nextPacketDueBy": {
              "type": "string",
              "format": "date",
              "description": "Tenth business day of the month after the month following the cutoff"
            },
            "stale": {
              "type": "boolean",
              "description": "True once nextPacketDueBy has passed with no newer packet"
            },
            "definitions": {
              "type": "object"
            },
            "sources": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "key",
                  "label",
                  "coverageStart",
                  "coverageEnd",
                  "extractedAt"
                ],
                "properties": {
                  "key": {
                    "type": "string"
                  },
                  "label": {
                    "type": "string"
                  },
                  "coverageStart": {
                    "type": "string",
                    "format": "date"
                  },
                  "coverageEnd": {
                    "type": "string",
                    "format": "date"
                  },
                  "extractedAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "therapists": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "key",
              "label",
              "role"
            ],
            "properties": {
              "key": {
                "type": "string"
              },
              "label": {
                "type": "string"
              },
              "role": {
                "type": "string",
                "enum": [
                  "clinician",
                  "owner",
                  "unassigned"
                ]
              }
            }
          }
        },
        "channels": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "key",
              "label"
            ],
            "properties": {
              "key": {
                "type": "string"
              },
              "label": {
                "type": "string"
              }
            }
          }
        },
        "cac": {
          "type": [
            "object",
            "null"
          ],
          "description": "Acquisition lens. Therapist CAC is allocated spend over attributed new clients; the practice blend is all approved spend over all actual new clients. While any new client in the window has no recorded channel, every practice channel CAC, and every therapist CAC or therapist channel row with new clients, is unavailable (attribution_incomplete, or no_attributed_clients for a therapist with no client on a recorded channel), as are all of a therapist's channel rows while that therapist has such a client; the blended and covered practice CAC stay.",
          "required": [
            "window",
            "therapists",
            "channels",
            "practice"
          ],
          "properties": {
            "window": {
              "type": "object",
              "properties": {
                "start": {
                  "type": "string",
                  "format": "date"
                },
                "end": {
                  "type": "string",
                  "format": "date"
                }
              }
            },
            "therapists": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "therapist",
                  "newClients",
                  "unattributedNewClients",
                  "allocatedSpendCents",
                  "cac",
                  "channels"
                ],
                "properties": {
                  "therapist": {
                    "type": "string"
                  },
                  "newClients": {
                    "type": "integer"
                  },
                  "unattributedNewClients": {
                    "type": "integer"
                  },
                  "allocatedSpendCents": {
                    "type": "integer"
                  },
                  "cac": {
                    "$ref": "#/$defs/PracticePacketFigure"
                  },
                  "channels": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "channel",
                        "newClients",
                        "allocatedSpendCents",
                        "cac"
                      ],
                      "properties": {
                        "channel": {
                          "type": "string"
                        },
                        "newClients": {
                          "type": "integer"
                        },
                        "allocatedSpendCents": {
                          "type": "integer"
                        },
                        "cac": {
                          "$ref": "#/$defs/PracticePacketFigure"
                        }
                      }
                    }
                  }
                }
              }
            },
            "channels": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "channel",
                  "newClients",
                  "spendCents",
                  "cac"
                ],
                "properties": {
                  "channel": {
                    "type": "string"
                  },
                  "newClients": {
                    "type": "integer"
                  },
                  "spendCents": {
                    "type": "integer"
                  },
                  "cac": {
                    "$ref": "#/$defs/PracticePacketFigure"
                  }
                }
              }
            },
            "practice": {
              "type": "object",
              "required": [
                "newClients",
                "attributedNewClients",
                "sourceSpendCents",
                "allocatedSpendCents",
                "unallocatedSpendCents",
                "blended",
                "covered"
              ],
              "properties": {
                "newClients": {
                  "type": "integer"
                },
                "attributedNewClients": {
                  "type": "integer"
                },
                "sourceSpendCents": {
                  "type": "integer"
                },
                "allocatedSpendCents": {
                  "type": "integer"
                },
                "unallocatedSpendCents": {
                  "type": "integer"
                },
                "blended": {
                  "$ref": "#/$defs/PracticePacketFigure"
                },
                "covered": {
                  "$ref": "#/$defs/PracticePacketFigure"
                }
              }
            }
          }
        },
        "serviceValue": {
          "type": [
            "object",
            "null"
          ],
          "description": "Service lens over the history window. LTV is net collections over unique clients served; LTGP subtracts actual direct service cost.",
          "required": [
            "historyStart",
            "cutoff",
            "historyComplete",
            "therapists",
            "practice"
          ],
          "properties": {
            "historyStart": {
              "type": "string",
              "format": "date"
            },
            "cutoff": {
              "type": "string",
              "format": "date"
            },
            "historyComplete": {
              "type": "boolean"
            },
            "therapists": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/PracticeServiceValueRow"
              }
            },
            "practice": {
              "$ref": "#/$defs/PracticeServiceValueRow"
            }
          }
        },
        "retention": {
          "type": [
            "object",
            "null"
          ],
          "description": "Monthly retention of the opening active-client cohort on a 90-day kept-appointment window; the practice figure uses the practice's own distinct counts.",
          "required": [
            "windowDays",
            "months"
          ],
          "properties": {
            "windowDays": {
              "type": "integer",
              "enum": [
                90
              ]
            },
            "months": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "month",
                  "openingSnapshot",
                  "closingSnapshot",
                  "lookbackStart",
                  "lookbackComplete",
                  "therapists",
                  "practice"
                ],
                "properties": {
                  "month": {
                    "type": "string"
                  },
                  "openingSnapshot": {
                    "type": "string",
                    "format": "date"
                  },
                  "closingSnapshot": {
                    "type": "string",
                    "format": "date"
                  },
                  "lookbackStart": {
                    "type": "string",
                    "format": "date"
                  },
                  "lookbackComplete": {
                    "type": "boolean"
                  },
                  "therapists": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "therapist",
                        "openingActive",
                        "retainedOpening",
                        "closingActive",
                        "newClients",
                        "reactivated",
                        "transfersIn",
                        "transfersOut",
                        "retention"
                      ],
                      "properties": {
                        "therapist": {
                          "type": "string"
                        },
                        "openingActive": {
                          "type": "integer"
                        },
                        "retainedOpening": {
                          "type": "integer"
                        },
                        "closingActive": {
                          "type": "integer"
                        },
                        "newClients": {
                          "type": "integer"
                        },
                        "reactivated": {
                          "type": "integer"
                        },
                        "transfersIn": {
                          "type": "integer"
                        },
                        "transfersOut": {
                          "type": "integer"
                        },
                        "retention": {
                          "$ref": "#/$defs/PracticePacketFigure"
                        }
                      }
                    }
                  },
                  "practice": {
                    "type": "object",
                    "required": [
                      "openingActive",
                      "retainedOpening",
                      "closingActive",
                      "newClients",
                      "reactivated",
                      "retention"
                    ],
                    "properties": {
                      "openingActive": {
                        "type": "integer"
                      },
                      "retainedOpening": {
                        "type": "integer"
                      },
                      "closingActive": {
                        "type": "integer"
                      },
                      "newClients": {
                        "type": "integer"
                      },
                      "reactivated": {
                        "type": "integer"
                      },
                      "retention": {
                        "$ref": "#/$defs/PracticePacketFigure"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "ltvToCac": {
          "type": [
            "object",
            "null"
          ],
          "description": "An acquired cohort's own collections through the cutoff against the same cohort's acquisition spend. While any new client in the window has no recorded channel, every therapist and channel ratio is unavailable (attribution_incomplete, or no_attributed_clients for a therapist with no client on a recorded channel); the blended ratio stays.",
          "required": [
            "cohortWindow",
            "observedThrough",
            "blended",
            "therapists",
            "channels"
          ],
          "properties": {
            "cohortWindow": {
              "type": "object",
              "properties": {
                "start": {
                  "type": "string",
                  "format": "date"
                },
                "end": {
                  "type": "string",
                  "format": "date"
                }
              }
            },
            "observedThrough": {
              "type": "string",
              "format": "date"
            },
            "blended": {
              "$ref": "#/$defs/PracticeLtvToCacRow"
            },
            "therapists": {
              "type": "array",
              "items": {
                "allOf": [
                  {
                    "$ref": "#/$defs/PracticeLtvToCacRow"
                  },
                  {
                    "type": "object",
                    "required": [
                      "therapist"
                    ],
                    "properties": {
                      "therapist": {
                        "type": "string"
                      }
                    }
                  }
                ]
              }
            },
            "channels": {
              "type": "array",
              "items": {
                "allOf": [
                  {
                    "$ref": "#/$defs/PracticeLtvToCacRow"
                  },
                  {
                    "type": "object",
                    "required": [
                      "channel"
                    ],
                    "properties": {
                      "channel": {
                        "type": "string"
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }
  },
  "$defs": {
    "PracticeLtvToCacRow": {
      "type": "object",
      "required": [
        "cohortNetCollectionsCents",
        "newClients",
        "spendCents",
        "ratio"
      ],
      "properties": {
        "cohortNetCollectionsCents": {
          "type": "integer"
        },
        "newClients": {
          "type": "integer"
        },
        "spendCents": {
          "type": "integer"
        },
        "ratio": {
          "$ref": "#/$defs/PracticePacketFigure"
        }
      }
    },
    "PracticePacketFigure": {
      "type": "object",
      "required": [
        "value",
        "reason"
      ],
      "description": "One computed figure, unrounded: cents for money, percent (0 to 100) for retention, a plain multiple for LTV:CAC. `value` is null exactly when `reason` says why; a known zero is a value.\n",
      "properties": {
        "value": {
          "type": [
            "number",
            "null"
          ]
        },
        "reason": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "no_new_clients",
            "no_attributed_clients",
            "attribution_incomplete",
            "no_clients_served",
            "no_opening_clients",
            "lookback_incomplete",
            "owner_policy_pending",
            "direct_cost_not_supplied",
            "direct_cost_incomplete",
            "no_acquisition_spend",
            null
          ]
        }
      }
    },
    "PracticeServiceValueRow": {
      "type": "object",
      "required": [
        "grossCollectionsCents",
        "refundsCents",
        "netCollectionsCents",
        "uniqueClientsServed",
        "directCostCents",
        "grossProfitCents",
        "ltv",
        "ltgp"
      ],
      "properties": {
        "therapist": {
          "type": "string",
          "description": "Absent on the practice row"
        },
        "grossCollectionsCents": {
          "type": "integer"
        },
        "refundsCents": {
          "type": "integer"
        },
        "netCollectionsCents": {
          "type": "integer"
        },
        "uniqueClientsServed": {
          "type": "integer"
        },
        "directCostCents": {
          "type": [
            "integer",
            "null"
          ]
        },
        "grossProfitCents": {
          "type": [
            "integer",
            "null"
          ]
        },
        "ltv": {
          "$ref": "#/$defs/PracticePacketFigure"
        },
        "ltgp": {
          "$ref": "#/$defs/PracticePacketFigure"
        }
      }
    }
  }
}