> ## Documentation Index
> Fetch the complete documentation index at: https://docs.octavehq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Compare Cohorts

> Test whether one cohort of deals does better than another, on win rate or a leading outcome (advanced within N days, faster than the stage median, next conversation positive). Cohorts are defined by event filters (or cohort A against every other deal). Returns each win rate with a 95% interval, the gap with its interval, a verdict (insufficient_evidence / no_material_difference / difference_to_watch / difference_to_investigate) with the strongest claim level the data supports, the definition of every number (formula, grain, clock, exclusions), the sample an unsettled question would need, an optional like-for-like check within a stratifying dimension, and caveats. REST twin of the compare_cohorts MCP tool.



## OpenAPI

````yaml post /api/v2/event/compare
openapi: 3.0.0
info:
  version: 5.4.0
  title: Octave API
  description: API for Octave workspace management and AI-powered content generation
servers:
  - url: https://app.octavehq.com
security:
  - ApiKeyAuth: []
paths:
  /api/v2/event/compare:
    post:
      tags:
        - Events
      summary: Compare Cohorts
      description: >-
        Test whether one cohort of deals does better than another, on win rate
        or a leading outcome (advanced within N days, faster than the stage
        median, next conversation positive). Cohorts are defined by event
        filters (or cohort A against every other deal). Returns each win rate
        with a 95% interval, the gap with its interval, a verdict
        (insufficient_evidence / no_material_difference / difference_to_watch /
        difference_to_investigate) with the strongest claim level the data
        supports, the definition of every number (formula, grain, clock,
        exclusions), the sample an unsettled question would need, an optional
        like-for-like check within a stratifying dimension, and caveats. REST
        twin of the compare_cohorts MCP tool.
      operationId: compareCohorts
      requestBody:
        description: Event window, shared filters and the two cohorts
        content:
          application/json:
            schema:
              type: object
              properties:
                startDate:
                  type: string
                  nullable: true
                  format: date-time
                  description: >-
                    Start date for event time range (ISO 8601 format). Defaults
                    to 14 days ago if not provided; the response's dataWindow
                    echoes what was used.
                endDate:
                  type: string
                  nullable: true
                  format: date-time
                  description: >-
                    End date for event time range. Defaults to the time of the
                    request, so events stamped in the future (a lost deal's
                    placeholder close date, for example) are left out; pass an
                    explicit later endDate to include them. The response's
                    dataWindow echoes what was used.
                filters:
                  type: object
                  properties:
                    entityMatchAll:
                      type: boolean
                      description: >-
                        Require every selected library entity, including
                        entities of the same category
                    eventOIds:
                      type: array
                      items:
                        type: string
                      description: Filter to these event oIds only
                    opportunityIds:
                      type: array
                      items:
                        type: string
                      description: >-
                        Filter to events linked to these opportunities. Accepts
                        Octave opportunity oIds (crmo_*) or the CRM's own deal
                        ids (Salesforce Id, HubSpot object id, Attio record
                        UUID) interchangeably
                    eventCategories:
                      type: array
                      items:
                        type: string
                        enum:
                          - EMAIL
                          - CALL
                          - CRM
                          - RESOURCE
                          - REVISION
                          - SOCIAL
                          - ADS
                          - PRODUCT
                          - UNKNOWN
                      description: Filter by event categories (CALL, EMAIL, CRM)
                    eventTypes:
                      type: array
                      items:
                        type: string
                        enum:
                          - EMAIL_SENT
                          - EMAIL_REPLY_RECEIVED
                          - CALL_TRANSCRIPT
                          - DEAL_WON
                          - DEAL_LOST
                          - OPPORTUNITY_CREATED
                          - MEETING_BOOKED
                          - RESOURCE_INDEXED
                          - RESOURCE_REINDEXED
                          - PROJECT_UPDATE
                          - TASK_COMPLETED
                          - ENTITY_CREATED
                          - ENTITY_UPDATED
                          - SOCIAL_MESSAGE_SENT
                          - SOCIAL_MESSAGE_RECEIVED
                          - SOCIAL_CONNECTION_SENT
                          - SOCIAL_CONNECTION_ACCEPTED
                          - AD_SET_PUBLISHED
                          - AD_PERFORMANCE_SNAPSHOT
                          - BULK_IMPORT_SUMMARY
                          - PROCESSING_NOT_APPLICABLE
                          - PROVIDER_EVENT_TYPE_UNKNOWN
                          - UNKNOWN
                      description: >-
                        Filter by specific event types (CALL_TRANSCRIPT,
                        EMAIL_SENT, DEAL_WON, etc.)
                    sentiments:
                      type: array
                      items:
                        type: string
                        enum:
                          - POSITIVE
                          - NEUTRAL
                          - NEGATIVE
                          - UNKNOWN
                      description: Filter by sentiment (POSITIVE, NEGATIVE, NEUTRAL, MIXED)
                    contactEmails:
                      type: array
                      items:
                        type: string
                      description: Filter by participant email addresses
                    companyDomains:
                      type: array
                      items:
                        type: string
                      description: Filter by company domains
                    outcomeFilters:
                      type: array
                      items:
                        type: string
                        enum:
                          - OPEN
                          - WON
                          - LOST
                          - POSITIVE_REPLY
                          - NEUTRAL_REPLY
                          - NEGATIVE_REPLY
                      description: >-
                        Filter by outcome (OPEN, WON, LOST, POSITIVE_REPLY,
                        NEUTRAL_REPLY, NEGATIVE_REPLY)
                    opportunityStatuses:
                      type: array
                      items:
                        type: string
                        enum:
                          - OPEN
                          - WON
                          - LOST
                      description: >-
                        Filter to events linked to deals with this status (OPEN,
                        WON, LOST)
                    dealMotions:
                      type: array
                      items:
                        type: string
                        enum:
                          - NET_NEW
                          - UPSELL
                          - CROSS_SELL
                          - RENEW_AND_RETAIN
                          - CONVERT_FREE_TO_PAID
                          - DISPLACE_INCUMBENT
                          - SERVICES
                          - PARTNER
                          - NON_COMMERCIAL
                      description: >-
                        Filter to events linked to deals whose CRM deal type
                        maps to these motions (NET_NEW, UPSELL, CROSS_SELL,
                        RENEW_AND_RETAIN, CONVERT_FREE_TO_PAID,
                        DISPLACE_INCUMBENT, SERVICES, PARTNER, NON_COMMERCIAL)
                    dealTypes:
                      type: array
                      items:
                        type: string
                      description: >-
                        Filter to events linked to deals with these raw CRM
                        deal-type labels (Salesforce Type, HubSpot dealtype),
                        case-insensitive
                    dealStages:
                      type: array
                      items:
                        type: string
                      description: >-
                        Filter to events linked to deals currently in these CRM
                        stages, by stage label or stage id, case-insensitive
                    dealStagesAtEvent:
                      type: array
                      items:
                        type: string
                      description: >-
                        Filter to events whose linked deal was in one of these
                        CRM stages WHEN THE EVENT HAPPENED (by stage label,
                        case-insensitive), from the deal's stage history —
                        unlike dealStages, which reads the deal's stage today.
                        Use it for 'what came up on calls during Discovery'. An
                        event whose deal has no recorded stage at that time does
                        not match.
                    pipelinePhases:
                      type: array
                      items:
                        type: string
                        enum:
                          - prospecting
                          - discovery
                          - evaluation
                          - negotiation
                          - commitment
                          - closed_won
                          - closed_lost
                      description: >-
                        Filter to events linked to deals whose stage maps to
                        these pipeline phases (prospecting, discovery,
                        evaluation, negotiation, commitment, closed_won,
                        closed_lost)
                    crmPipelines:
                      type: array
                      items:
                        type: string
                      description: >-
                        Filter to events linked to deals in these CRM pipelines,
                        by pipeline id or name (case-insensitive name)
                    minStalledDays:
                      type: number
                      description: >-
                        Filter to events linked to an OPEN deal that has sat in
                        its current stage at least this many days
                    minDealAmount:
                      type: number
                      description: Minimum deal amount filter
                    maxDealAmount:
                      type: number
                      description: Maximum deal amount filter
                    offerings:
                      type: array
                      items:
                        type: string
                      description: Filter by offering oIds
                    personas:
                      type: array
                      items:
                        type: string
                      description: >-
                        Filter by persona oIds (events must match these
                        personas)
                    segments:
                      type: array
                      items:
                        type: string
                      description: Filter by segment oIds
                    tags:
                      type: array
                      items:
                        type: string
                      description: >-
                        Filter by reporting tag oIds (from any tag group, on any
                        library entity type). Resolved to the entities carrying
                        those tags; multiple tags are OR'd.
                    useCases:
                      type: array
                      items:
                        type: string
                      description: Filter by use case oIds
                    references:
                      type: array
                      items:
                        type: string
                      description: Filter by reference customer oIds
                    competitors:
                      type: array
                      items:
                        type: string
                      description: Filter by competitor oIds
                    alternatives:
                      type: array
                      items:
                        type: string
                      description: Filter by alternative oIds
                    buyingTriggers:
                      type: array
                      items:
                        type: string
                      description: Filter by buying trigger oIds
                    coreFeatures:
                      type: array
                      items:
                        type: string
                      description: Filter by core feature oIds
                    objections:
                      type: array
                      items:
                        type: string
                      description: Filter by objection oIds
                    proofPoints:
                      type: array
                      items:
                        type: string
                      description: Filter by proof point oIds
                    motionTypes:
                      type: array
                      items:
                        type: string
                        enum:
                          - NET_NEW
                          - UPSELL
                          - CROSS_SELL
                          - CONVERT_FREE_TO_PAID
                          - RENEW_AND_RETAIN
                          - DISPLACE_INCUMBENT
                      description: Filter by motion type (NET_NEW, UPSELL)
                    customerScope:
                      type: string
                      enum:
                        - ALL
                        - NEW_CUSTOMERS
                        - EXISTING_CUSTOMERS
                      description: >-
                        Customer-scope view (NEW_CUSTOMERS /
                        EXISTING_CUSTOMERS); ALL or absent applies no filter
                    callPurposes:
                      type: array
                      items:
                        type: string
                        enum:
                          - DISCOVERY
                          - DEMO
                          - TECHNICAL_EVALUATION
                          - WORKING_SESSION
                          - NEGOTIATION_PRICING
                          - ONBOARDING
                          - CHECK_IN_SUCCESS
                          - QBR_RENEWAL
                          - EXPANSION_UPSELL
                          - ESCALATION_CHURN_RISK
                          - SUPPORT
                          - INTERNAL_SYNC
                          - OTHER
                      description: >-
                        Filter calls by classified purpose (DISCOVERY, DEMO,
                        TECHNICAL_EVALUATION, WORKING_SESSION,
                        NEGOTIATION_PRICING, ONBOARDING, CHECK_IN_SUCCESS,
                        QBR_RENEWAL, EXPANSION_UPSELL, ESCALATION_CHURN_RISK,
                        SUPPORT, INTERNAL_SYNC, OTHER)
                    unmatchedOnly:
                      type: boolean
                      description: >-
                        When true, only return events that have findings with no
                        library entity matches
                  description: >-
                    Filters to INCLUDE events: event type/category, company,
                    contact, sentiment, call purpose, outcome, deal amount,
                    library entity oIds (offerings, personas, segments, tags,
                    use cases, competitors, alternatives, buying triggers, core
                    features, objections, proof points, references), motion
                    types, customer scope, and CRM deal context (opportunityIds,
                    opportunityStatuses, dealMotions, dealTypes, dealStages,
                    pipelinePhases, crmPipelines, minStalledDays). Deal filters
                    AND on the same linked deal; values within one filter are
                    OR'd.
                exclude:
                  type: object
                  properties:
                    eventCategories:
                      type: array
                      items:
                        type: string
                        enum:
                          - EMAIL
                          - CALL
                          - CRM
                          - RESOURCE
                          - REVISION
                          - SOCIAL
                          - ADS
                          - PRODUCT
                          - UNKNOWN
                      description: Filter by event categories (CALL, EMAIL, CRM)
                    eventTypes:
                      type: array
                      items:
                        type: string
                        enum:
                          - EMAIL_SENT
                          - EMAIL_REPLY_RECEIVED
                          - CALL_TRANSCRIPT
                          - DEAL_WON
                          - DEAL_LOST
                          - OPPORTUNITY_CREATED
                          - MEETING_BOOKED
                          - RESOURCE_INDEXED
                          - RESOURCE_REINDEXED
                          - PROJECT_UPDATE
                          - TASK_COMPLETED
                          - ENTITY_CREATED
                          - ENTITY_UPDATED
                          - SOCIAL_MESSAGE_SENT
                          - SOCIAL_MESSAGE_RECEIVED
                          - SOCIAL_CONNECTION_SENT
                          - SOCIAL_CONNECTION_ACCEPTED
                          - AD_SET_PUBLISHED
                          - AD_PERFORMANCE_SNAPSHOT
                          - BULK_IMPORT_SUMMARY
                          - PROCESSING_NOT_APPLICABLE
                          - PROVIDER_EVENT_TYPE_UNKNOWN
                          - UNKNOWN
                      description: >-
                        Filter by specific event types (CALL_TRANSCRIPT,
                        EMAIL_SENT, DEAL_WON, etc.)
                    sentiments:
                      type: array
                      items:
                        type: string
                        enum:
                          - POSITIVE
                          - NEUTRAL
                          - NEGATIVE
                          - UNKNOWN
                      description: Filter by sentiment (POSITIVE, NEGATIVE, NEUTRAL, MIXED)
                    contactEmails:
                      type: array
                      items:
                        type: string
                      description: Filter by participant email addresses
                    companyDomains:
                      type: array
                      items:
                        type: string
                      description: Filter by company domains
                    outcomeFilters:
                      type: array
                      items:
                        type: string
                        enum:
                          - OPEN
                          - WON
                          - LOST
                          - POSITIVE_REPLY
                          - NEUTRAL_REPLY
                          - NEGATIVE_REPLY
                      description: >-
                        Exclude by outcome (OPEN, WON, LOST, POSITIVE_REPLY,
                        NEUTRAL_REPLY, NEGATIVE_REPLY)
                    opportunityStatuses:
                      type: array
                      items:
                        type: string
                        enum:
                          - OPEN
                          - WON
                          - LOST
                      description: Exclude by opportunity status (OPEN, WON, LOST)
                    minDealAmount:
                      type: number
                      description: Minimum deal amount filter
                    maxDealAmount:
                      type: number
                      description: Maximum deal amount filter
                    offerings:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these offering oIds
                    personas:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these persona oIds
                    segments:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these segment oIds
                    tags:
                      type: array
                      items:
                        type: string
                      description: >-
                        Exclude events matching any library entity that carries
                        these reporting tag oIds (any tag group; OR'd).
                    useCases:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these use case oIds
                    references:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these reference customer oIds
                    competitors:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these competitor oIds
                    alternatives:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these alternative oIds
                    buyingTriggers:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these buying trigger oIds
                    coreFeatures:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these core feature oIds
                    objections:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these objection oIds
                    proofPoints:
                      type: array
                      items:
                        type: string
                      description: Exclude events matching these proof point oIds
                    motionTypes:
                      type: array
                      items:
                        type: string
                        enum:
                          - NET_NEW
                          - UPSELL
                          - CROSS_SELL
                          - CONVERT_FREE_TO_PAID
                          - RENEW_AND_RETAIN
                          - DISPLACE_INCUMBENT
                      description: >-
                        Exclude events matching these motion types (NET_NEW,
                        UPSELL)
                    callPurposes:
                      type: array
                      items:
                        type: string
                        enum:
                          - DISCOVERY
                          - DEMO
                          - TECHNICAL_EVALUATION
                          - WORKING_SESSION
                          - NEGOTIATION_PRICING
                          - ONBOARDING
                          - CHECK_IN_SUCCESS
                          - QBR_RENEWAL
                          - EXPANSION_UPSELL
                          - ESCALATION_CHURN_RISK
                          - SUPPORT
                          - INTERNAL_SYNC
                          - OTHER
                      description: >-
                        Exclude calls with these classified purposes (e.g.
                        SUPPORT, INTERNAL_SYNC)
                    dealMotions:
                      type: array
                      items:
                        type: string
                        enum:
                          - NET_NEW
                          - UPSELL
                          - CROSS_SELL
                          - RENEW_AND_RETAIN
                          - CONVERT_FREE_TO_PAID
                          - DISPLACE_INCUMBENT
                          - SERVICES
                          - PARTNER
                          - NON_COMMERCIAL
                      description: >-
                        Exclude events linked to deals whose CRM deal type maps
                        to these motions
                    dealTypes:
                      type: array
                      items:
                        type: string
                      description: >-
                        Exclude events linked to deals with these raw CRM
                        deal-type labels, case-insensitive
                    dealStages:
                      type: array
                      items:
                        type: string
                      description: >-
                        Exclude events linked to deals currently in these CRM
                        stages, by stage label or stage id, case-insensitive
                    pipelinePhases:
                      type: array
                      items:
                        type: string
                        enum:
                          - prospecting
                          - discovery
                          - evaluation
                          - negotiation
                          - commitment
                          - closed_won
                          - closed_lost
                      description: >-
                        Exclude events linked to deals whose stage maps to these
                        pipeline phases
                  description: >-
                    Filters to EXCLUDE events matching these criteria (same
                    shape as the entity/outcome match filters)
                excludeTags:
                  type: array
                  items:
                    type: string
                  description: >-
                    Exclude events matching any library entity that carries
                    these reporting tag oIds. Use list_tag_groups to resolve tag
                    oIds. Multiple tags are OR'd.
                cohortA:
                  type: object
                  properties:
                    label:
                      type: string
                      minLength: 1
                      description: Short name used in the verdict, e.g. 'Intake mentioned'.
                    filters:
                      type: object
                      properties:
                        entityMatchAll:
                          type: boolean
                          description: >-
                            Require every selected library entity, including
                            entities of the same category
                        eventOIds:
                          type: array
                          items:
                            type: string
                          description: Filter to these event oIds only
                        opportunityIds:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events linked to these opportunities.
                            Accepts Octave opportunity oIds (crmo_*) or the
                            CRM's own deal ids (Salesforce Id, HubSpot object
                            id, Attio record UUID) interchangeably
                        eventCategories:
                          type: array
                          items:
                            type: string
                            enum:
                              - EMAIL
                              - CALL
                              - CRM
                              - RESOURCE
                              - REVISION
                              - SOCIAL
                              - ADS
                              - PRODUCT
                              - UNKNOWN
                          description: Filter by event categories (CALL, EMAIL, CRM)
                        eventTypes:
                          type: array
                          items:
                            type: string
                            enum:
                              - EMAIL_SENT
                              - EMAIL_REPLY_RECEIVED
                              - CALL_TRANSCRIPT
                              - DEAL_WON
                              - DEAL_LOST
                              - OPPORTUNITY_CREATED
                              - MEETING_BOOKED
                              - RESOURCE_INDEXED
                              - RESOURCE_REINDEXED
                              - PROJECT_UPDATE
                              - TASK_COMPLETED
                              - ENTITY_CREATED
                              - ENTITY_UPDATED
                              - SOCIAL_MESSAGE_SENT
                              - SOCIAL_MESSAGE_RECEIVED
                              - SOCIAL_CONNECTION_SENT
                              - SOCIAL_CONNECTION_ACCEPTED
                              - AD_SET_PUBLISHED
                              - AD_PERFORMANCE_SNAPSHOT
                              - BULK_IMPORT_SUMMARY
                              - PROCESSING_NOT_APPLICABLE
                              - PROVIDER_EVENT_TYPE_UNKNOWN
                              - UNKNOWN
                          description: >-
                            Filter by specific event types (CALL_TRANSCRIPT,
                            EMAIL_SENT, DEAL_WON, etc.)
                        sentiments:
                          type: array
                          items:
                            type: string
                            enum:
                              - POSITIVE
                              - NEUTRAL
                              - NEGATIVE
                              - UNKNOWN
                          description: >-
                            Filter by sentiment (POSITIVE, NEGATIVE, NEUTRAL,
                            MIXED)
                        contactEmails:
                          type: array
                          items:
                            type: string
                          description: Filter by participant email addresses
                        companyDomains:
                          type: array
                          items:
                            type: string
                          description: Filter by company domains
                        outcomeFilters:
                          type: array
                          items:
                            type: string
                            enum:
                              - OPEN
                              - WON
                              - LOST
                              - POSITIVE_REPLY
                              - NEUTRAL_REPLY
                              - NEGATIVE_REPLY
                          description: >-
                            Filter by outcome (OPEN, WON, LOST, POSITIVE_REPLY,
                            NEUTRAL_REPLY, NEGATIVE_REPLY)
                        opportunityStatuses:
                          type: array
                          items:
                            type: string
                            enum:
                              - OPEN
                              - WON
                              - LOST
                          description: >-
                            Filter to events linked to deals with this status
                            (OPEN, WON, LOST)
                        dealMotions:
                          type: array
                          items:
                            type: string
                            enum:
                              - NET_NEW
                              - UPSELL
                              - CROSS_SELL
                              - RENEW_AND_RETAIN
                              - CONVERT_FREE_TO_PAID
                              - DISPLACE_INCUMBENT
                              - SERVICES
                              - PARTNER
                              - NON_COMMERCIAL
                          description: >-
                            Filter to events linked to deals whose CRM deal type
                            maps to these motions (NET_NEW, UPSELL, CROSS_SELL,
                            RENEW_AND_RETAIN, CONVERT_FREE_TO_PAID,
                            DISPLACE_INCUMBENT, SERVICES, PARTNER,
                            NON_COMMERCIAL)
                        dealTypes:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events linked to deals with these raw CRM
                            deal-type labels (Salesforce Type, HubSpot
                            dealtype), case-insensitive
                        dealStages:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events linked to deals currently in these
                            CRM stages, by stage label or stage id,
                            case-insensitive
                        dealStagesAtEvent:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events whose linked deal was in one of
                            these CRM stages WHEN THE EVENT HAPPENED (by stage
                            label, case-insensitive), from the deal's stage
                            history — unlike dealStages, which reads the deal's
                            stage today. Use it for 'what came up on calls
                            during Discovery'. An event whose deal has no
                            recorded stage at that time does not match.
                        pipelinePhases:
                          type: array
                          items:
                            type: string
                            enum:
                              - prospecting
                              - discovery
                              - evaluation
                              - negotiation
                              - commitment
                              - closed_won
                              - closed_lost
                          description: >-
                            Filter to events linked to deals whose stage maps to
                            these pipeline phases (prospecting, discovery,
                            evaluation, negotiation, commitment, closed_won,
                            closed_lost)
                        crmPipelines:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events linked to deals in these CRM
                            pipelines, by pipeline id or name (case-insensitive
                            name)
                        minStalledDays:
                          type: number
                          description: >-
                            Filter to events linked to an OPEN deal that has sat
                            in its current stage at least this many days
                        minDealAmount:
                          type: number
                          description: Minimum deal amount filter
                        maxDealAmount:
                          type: number
                          description: Maximum deal amount filter
                        offerings:
                          type: array
                          items:
                            type: string
                          description: Filter by offering oIds
                        personas:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter by persona oIds (events must match these
                            personas)
                        segments:
                          type: array
                          items:
                            type: string
                          description: Filter by segment oIds
                        tags:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter by reporting tag oIds (from any tag group, on
                            any library entity type). Resolved to the entities
                            carrying those tags; multiple tags are OR'd.
                        useCases:
                          type: array
                          items:
                            type: string
                          description: Filter by use case oIds
                        references:
                          type: array
                          items:
                            type: string
                          description: Filter by reference customer oIds
                        competitors:
                          type: array
                          items:
                            type: string
                          description: Filter by competitor oIds
                        alternatives:
                          type: array
                          items:
                            type: string
                          description: Filter by alternative oIds
                        buyingTriggers:
                          type: array
                          items:
                            type: string
                          description: Filter by buying trigger oIds
                        coreFeatures:
                          type: array
                          items:
                            type: string
                          description: Filter by core feature oIds
                        objections:
                          type: array
                          items:
                            type: string
                          description: Filter by objection oIds
                        proofPoints:
                          type: array
                          items:
                            type: string
                          description: Filter by proof point oIds
                        motionTypes:
                          type: array
                          items:
                            type: string
                            enum:
                              - NET_NEW
                              - UPSELL
                              - CROSS_SELL
                              - CONVERT_FREE_TO_PAID
                              - RENEW_AND_RETAIN
                              - DISPLACE_INCUMBENT
                          description: Filter by motion type (NET_NEW, UPSELL)
                        customerScope:
                          type: string
                          enum:
                            - ALL
                            - NEW_CUSTOMERS
                            - EXISTING_CUSTOMERS
                          description: >-
                            Customer-scope view (NEW_CUSTOMERS /
                            EXISTING_CUSTOMERS); ALL or absent applies no filter
                        callPurposes:
                          type: array
                          items:
                            type: string
                            enum:
                              - DISCOVERY
                              - DEMO
                              - TECHNICAL_EVALUATION
                              - WORKING_SESSION
                              - NEGOTIATION_PRICING
                              - ONBOARDING
                              - CHECK_IN_SUCCESS
                              - QBR_RENEWAL
                              - EXPANSION_UPSELL
                              - ESCALATION_CHURN_RISK
                              - SUPPORT
                              - INTERNAL_SYNC
                              - OTHER
                          description: >-
                            Filter calls by classified purpose (DISCOVERY, DEMO,
                            TECHNICAL_EVALUATION, WORKING_SESSION,
                            NEGOTIATION_PRICING, ONBOARDING, CHECK_IN_SUCCESS,
                            QBR_RENEWAL, EXPANSION_UPSELL,
                            ESCALATION_CHURN_RISK, SUPPORT, INTERNAL_SYNC,
                            OTHER)
                        unmatchedOnly:
                          type: boolean
                          description: >-
                            When true, only return events that have findings
                            with no library entity matches
                      description: >-
                        What puts a deal in this cohort: event filters, ANDed
                        with the shared `filters`. A deal belongs if ANY of its
                        events in the window match — e.g. { useCases: ['uc_…'] }
                        is 'deals where this use case came up'.
                  required:
                    - label
                cohortB:
                  type: object
                  properties:
                    label:
                      type: string
                      minLength: 1
                      description: Short name used in the verdict, e.g. 'Intake mentioned'.
                    filters:
                      type: object
                      properties:
                        entityMatchAll:
                          type: boolean
                          description: >-
                            Require every selected library entity, including
                            entities of the same category
                        eventOIds:
                          type: array
                          items:
                            type: string
                          description: Filter to these event oIds only
                        opportunityIds:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events linked to these opportunities.
                            Accepts Octave opportunity oIds (crmo_*) or the
                            CRM's own deal ids (Salesforce Id, HubSpot object
                            id, Attio record UUID) interchangeably
                        eventCategories:
                          type: array
                          items:
                            type: string
                            enum:
                              - EMAIL
                              - CALL
                              - CRM
                              - RESOURCE
                              - REVISION
                              - SOCIAL
                              - ADS
                              - PRODUCT
                              - UNKNOWN
                          description: Filter by event categories (CALL, EMAIL, CRM)
                        eventTypes:
                          type: array
                          items:
                            type: string
                            enum:
                              - EMAIL_SENT
                              - EMAIL_REPLY_RECEIVED
                              - CALL_TRANSCRIPT
                              - DEAL_WON
                              - DEAL_LOST
                              - OPPORTUNITY_CREATED
                              - MEETING_BOOKED
                              - RESOURCE_INDEXED
                              - RESOURCE_REINDEXED
                              - PROJECT_UPDATE
                              - TASK_COMPLETED
                              - ENTITY_CREATED
                              - ENTITY_UPDATED
                              - SOCIAL_MESSAGE_SENT
                              - SOCIAL_MESSAGE_RECEIVED
                              - SOCIAL_CONNECTION_SENT
                              - SOCIAL_CONNECTION_ACCEPTED
                              - AD_SET_PUBLISHED
                              - AD_PERFORMANCE_SNAPSHOT
                              - BULK_IMPORT_SUMMARY
                              - PROCESSING_NOT_APPLICABLE
                              - PROVIDER_EVENT_TYPE_UNKNOWN
                              - UNKNOWN
                          description: >-
                            Filter by specific event types (CALL_TRANSCRIPT,
                            EMAIL_SENT, DEAL_WON, etc.)
                        sentiments:
                          type: array
                          items:
                            type: string
                            enum:
                              - POSITIVE
                              - NEUTRAL
                              - NEGATIVE
                              - UNKNOWN
                          description: >-
                            Filter by sentiment (POSITIVE, NEGATIVE, NEUTRAL,
                            MIXED)
                        contactEmails:
                          type: array
                          items:
                            type: string
                          description: Filter by participant email addresses
                        companyDomains:
                          type: array
                          items:
                            type: string
                          description: Filter by company domains
                        outcomeFilters:
                          type: array
                          items:
                            type: string
                            enum:
                              - OPEN
                              - WON
                              - LOST
                              - POSITIVE_REPLY
                              - NEUTRAL_REPLY
                              - NEGATIVE_REPLY
                          description: >-
                            Filter by outcome (OPEN, WON, LOST, POSITIVE_REPLY,
                            NEUTRAL_REPLY, NEGATIVE_REPLY)
                        opportunityStatuses:
                          type: array
                          items:
                            type: string
                            enum:
                              - OPEN
                              - WON
                              - LOST
                          description: >-
                            Filter to events linked to deals with this status
                            (OPEN, WON, LOST)
                        dealMotions:
                          type: array
                          items:
                            type: string
                            enum:
                              - NET_NEW
                              - UPSELL
                              - CROSS_SELL
                              - RENEW_AND_RETAIN
                              - CONVERT_FREE_TO_PAID
                              - DISPLACE_INCUMBENT
                              - SERVICES
                              - PARTNER
                              - NON_COMMERCIAL
                          description: >-
                            Filter to events linked to deals whose CRM deal type
                            maps to these motions (NET_NEW, UPSELL, CROSS_SELL,
                            RENEW_AND_RETAIN, CONVERT_FREE_TO_PAID,
                            DISPLACE_INCUMBENT, SERVICES, PARTNER,
                            NON_COMMERCIAL)
                        dealTypes:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events linked to deals with these raw CRM
                            deal-type labels (Salesforce Type, HubSpot
                            dealtype), case-insensitive
                        dealStages:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events linked to deals currently in these
                            CRM stages, by stage label or stage id,
                            case-insensitive
                        dealStagesAtEvent:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events whose linked deal was in one of
                            these CRM stages WHEN THE EVENT HAPPENED (by stage
                            label, case-insensitive), from the deal's stage
                            history — unlike dealStages, which reads the deal's
                            stage today. Use it for 'what came up on calls
                            during Discovery'. An event whose deal has no
                            recorded stage at that time does not match.
                        pipelinePhases:
                          type: array
                          items:
                            type: string
                            enum:
                              - prospecting
                              - discovery
                              - evaluation
                              - negotiation
                              - commitment
                              - closed_won
                              - closed_lost
                          description: >-
                            Filter to events linked to deals whose stage maps to
                            these pipeline phases (prospecting, discovery,
                            evaluation, negotiation, commitment, closed_won,
                            closed_lost)
                        crmPipelines:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter to events linked to deals in these CRM
                            pipelines, by pipeline id or name (case-insensitive
                            name)
                        minStalledDays:
                          type: number
                          description: >-
                            Filter to events linked to an OPEN deal that has sat
                            in its current stage at least this many days
                        minDealAmount:
                          type: number
                          description: Minimum deal amount filter
                        maxDealAmount:
                          type: number
                          description: Maximum deal amount filter
                        offerings:
                          type: array
                          items:
                            type: string
                          description: Filter by offering oIds
                        personas:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter by persona oIds (events must match these
                            personas)
                        segments:
                          type: array
                          items:
                            type: string
                          description: Filter by segment oIds
                        tags:
                          type: array
                          items:
                            type: string
                          description: >-
                            Filter by reporting tag oIds (from any tag group, on
                            any library entity type). Resolved to the entities
                            carrying those tags; multiple tags are OR'd.
                        useCases:
                          type: array
                          items:
                            type: string
                          description: Filter by use case oIds
                        references:
                          type: array
                          items:
                            type: string
                          description: Filter by reference customer oIds
                        competitors:
                          type: array
                          items:
                            type: string
                          description: Filter by competitor oIds
                        alternatives:
                          type: array
                          items:
                            type: string
                          description: Filter by alternative oIds
                        buyingTriggers:
                          type: array
                          items:
                            type: string
                          description: Filter by buying trigger oIds
                        coreFeatures:
                          type: array
                          items:
                            type: string
                          description: Filter by core feature oIds
                        objections:
                          type: array
                          items:
                            type: string
                          description: Filter by objection oIds
                        proofPoints:
                          type: array
                          items:
                            type: string
                          description: Filter by proof point oIds
                        motionTypes:
                          type: array
                          items:
                            type: string
                            enum:
                              - NET_NEW
                              - UPSELL
                              - CROSS_SELL
                              - CONVERT_FREE_TO_PAID
                              - RENEW_AND_RETAIN
                              - DISPLACE_INCUMBENT
                          description: Filter by motion type (NET_NEW, UPSELL)
                        customerScope:
                          type: string
                          enum:
                            - ALL
                            - NEW_CUSTOMERS
                            - EXISTING_CUSTOMERS
                          description: >-
                            Customer-scope view (NEW_CUSTOMERS /
                            EXISTING_CUSTOMERS); ALL or absent applies no filter
                        callPurposes:
                          type: array
                          items:
                            type: string
                            enum:
                              - DISCOVERY
                              - DEMO
                              - TECHNICAL_EVALUATION
                              - WORKING_SESSION
                              - NEGOTIATION_PRICING
                              - ONBOARDING
                              - CHECK_IN_SUCCESS
                              - QBR_RENEWAL
                              - EXPANSION_UPSELL
                              - ESCALATION_CHURN_RISK
                              - SUPPORT
                              - INTERNAL_SYNC
                              - OTHER
                          description: >-
                            Filter calls by classified purpose (DISCOVERY, DEMO,
                            TECHNICAL_EVALUATION, WORKING_SESSION,
                            NEGOTIATION_PRICING, ONBOARDING, CHECK_IN_SUCCESS,
                            QBR_RENEWAL, EXPANSION_UPSELL,
                            ESCALATION_CHURN_RISK, SUPPORT, INTERNAL_SYNC,
                            OTHER)
                        unmatchedOnly:
                          type: boolean
                          description: >-
                            When true, only return events that have findings
                            with no library entity matches
                      description: >-
                        What puts a deal in this cohort: event filters, ANDed
                        with the shared `filters`. A deal belongs if ANY of its
                        events in the window match — e.g. { useCases: ['uc_…'] }
                        is 'deals where this use case came up'.
                  required:
                    - label
                  description: >-
                    The comparison group. OMIT it to compare cohort A against
                    every other deal in the window — the usual question ('do
                    deals where X came up win more than deals where it
                    didn't?').
                outcome:
                  oneOf:
                    - type: object
                      properties:
                        metric:
                          type: string
                          enum:
                            - win_rate
                      required:
                        - metric
                    - type: object
                      properties:
                        metric:
                          type: string
                          enum:
                            - advanced_within_days
                        days:
                          type: integer
                          minimum: 7
                          maximum: 180
                          default: 30
                          description: >-
                            How long after the conversation the deal has to
                            move.
                      required:
                        - metric
                    - type: object
                      properties:
                        metric:
                          type: string
                          enum:
                            - faster_than_stage_median
                      required:
                        - metric
                    - type: object
                      properties:
                        metric:
                          type: string
                          enum:
                            - next_conversation_positive
                      required:
                        - metric
                  default:
                    metric: win_rate
                  description: >-
                    The outcome the two cohorts are compared on. win_rate
                    (default): won / closed — the truest and the slowest.
                    advanced_within_days: the deal reached a later pipeline
                    phase (not closed-lost) within `days` of its first matching
                    conversation. faster_than_stage_median: the deal left the
                    CRM stage it was in at that conversation, for a stage other
                    than closed-lost, in less time than this workspace's median
                    for that stage. next_conversation_positive: the deal's next
                    conversation after it had POSITIVE overall sentiment. Use a
                    leading outcome when win_rate returns insufficient_evidence;
                    say which outcome a figure is about whenever you quote it.
                linkScope:
                  type: string
                  enum:
                    - crm_linked
                    - single_candidate
                    - outcome_attribution
                    - account_associated
                  description: >-
                    Which conversations count as belonging to a deal. OMIT it to
                    use the workspace's own default (set beside its CRM
                    mappings), or the product default, outcome_attribution, when
                    the workspace never chose; the response says which applied
                    in `linkScopeSource`. Which event-to-deal links establish
                    that a conversation belongs to a deal. outcome_attribution
                    (default): the product's own rule, the one behind the win
                    rates in Insights — attribution links, links the CRM or a
                    person made, links by a participant's contact email, and
                    company-domain links only on a deal with at least two of
                    them. Figures at this scope are comparable with Insights; at
                    the others they are not. It includes a conversation matched
                    by email to every deal its contact sits on, so on accounts
                    with many open deals a cohort is 'deals at accounts where
                    this came up' more than 'deals where it came up'.
                    crm_linked: only links the CRM or a person made —
                    'CRM-linked deals with a matching conversation'. The firmest
                    association and a much smaller, differently selected
                    population; not an unbiased one. single_candidate:
                    crm_linked plus an inferred link when the event reaches
                    exactly one deal. account_associated: every link. The
                    response reports the comparison under all four
                    (acrossLinkScopes), so you can see whether the direction
                    holds.
                stratifyBy:
                  type: object
                  properties:
                    by:
                      type: string
                      enum:
                        - segment
                        - persona
                        - use_case
                        - core_feature
                        - competitor
                        - alternative
                        - buying_trigger
                        - objection
                        - proof_point
                        - reference
                        - tag_group
                        - offering
                        - offering_of_core_feature
                        - company
                        - person
                        - speaker_side
                        - deal_stage_at_event
                      description: >-
                        What to group by. A library entity type (use_case,
                        segment, persona, competitor, objection, …) groups by
                        the entities matched on each event. 'tag_group' groups
                        by the values of one tag group (give tagGroupOId) — e.g.
                        use cases rolled up by Imperative. 'company' and
                        'person' group by who the event was with (person =
                        external contacts). 'offering' groups by the products,
                        services and solutions a finding on the event was
                        matched to directly — the offering was what was talked
                        about. 'offering_of_core_feature' rolls matched
                        CAPABILITIES up to the offering each belongs to in the
                        library today ('(no parent offering)' when a capability
                        has none) — use it to compare products by the
                        capabilities that came up. The two are different
                        relations and give different answers; neither says what
                        a deal SOLD or what the account OWNS. A conversation
                        that touches two offerings counts under both. An
                        offering match classifies the whole conversation rather
                        than quoting someone, so 'offering' crossed with
                        speaker_side is always 'unknown'. 'speaker_side' groups
                        by internal vs external speaker. 'deal_stage_at_event'
                        groups by the CRM stage the linked deal was in WHEN the
                        event happened, not its stage today.
                    tagGroupOId:
                      type: string
                      description: >-
                        Required when by = 'tag_group' (tg_...); ignored
                        otherwise.
                  required:
                    - by
                  description: >-
                    Also make the comparison WITHIN each value of this dimension
                    and pool the result. Use { by: 'segment' } (or a tag group,
                    or deal_stage_at_event) whenever the cohorts could simply
                    sit in different kinds of deal — it is what tells a real
                    effect from a mix effect.
                materialGapPoints:
                  type: number
                  minimum: 1
                  maximum: 50
                  default: 10
                  description: >-
                    The gap, in PERCENTAGE POINTS, below which two rates count
                    as alike — what the business would not act on. Only used to
                    decide no_material_difference. Choose it BEFORE looking at
                    the result. The default is a software default, not a
                    threshold anyone has endorsed; at a low base rate (say 15%)
                    a smaller margin such as 5 is more sensible. It never
                    suppresses the observed difference.
                comparisonsDeclared:
                  type: integer
                  minimum: 1
                  maximum: 1000
                  default: 1
                  description: >-
                    How many comparisons you are making in this analysis,
                    INCLUDING this one. If you are testing 12 use cases to see
                    which wins more, pass 12 on each call: some will look
                    significant by chance, and the verdict corrects for it.
                    Leave at 1 only for a single, pre-planned question.
              required:
                - cohortA
      responses:
        '200':
          description: Compare Cohorts
          content:
            application/json:
              schema:
                type: object
                properties:
                  _metadata:
                    $ref: '#/components/schemas/Metadata'
                  definition:
                    type: object
                    properties:
                      metric:
                        type: string
                        enum:
                          - win_rate
                          - advanced_within_days
                          - faster_than_stage_median
                          - next_conversation_positive
                      label:
                        type: string
                        description: The outcome in words, for quoting.
                      formula:
                        type: string
                      grain:
                        type: string
                      membership:
                        type: string
                      clock:
                        type: string
                      exclusions:
                        type: array
                        items:
                          type: string
                      linkScope:
                        type: string
                        description: >-
                          Which event-to-deal links establish membership, in
                          words.
                      orderRule:
                        type: string
                        description: >-
                          How a conversation is shown to precede the deal's
                          outcome, and when that order is unknown.
                      materialGapPoints:
                        type: number
                        description: >-
                          The gap, in percentage points, below which two rates
                          are called alike. A software default unless the caller
                          set it — not a threshold the business has endorsed.
                      currency:
                        type: string
                        description: The basis of every money figure.
                    required:
                      - metric
                      - label
                      - formula
                      - grain
                      - membership
                      - clock
                      - exclusions
                      - linkScope
                      - orderRule
                      - materialGapPoints
                      - currency
                    description: >-
                      How every number here is defined: what is counted, over
                      which clock, and what is left out. State the relevant
                      parts when quoting a figure.
                  linkScope:
                    type: string
                    enum:
                      - crm_linked
                      - single_candidate
                      - outcome_attribution
                      - account_associated
                    description: >-
                      Which event-to-deal links establish that a conversation
                      belongs to a deal. outcome_attribution (default): the
                      product's own rule, the one behind the win rates in
                      Insights — attribution links, links the CRM or a person
                      made, links by a participant's contact email, and
                      company-domain links only on a deal with at least two of
                      them. Figures at this scope are comparable with Insights;
                      at the others they are not. It includes a conversation
                      matched by email to every deal its contact sits on, so on
                      accounts with many open deals a cohort is 'deals at
                      accounts where this came up' more than 'deals where it
                      came up'. crm_linked: only links the CRM or a person made
                      — 'CRM-linked deals with a matching conversation'. The
                      firmest association and a much smaller, differently
                      selected population; not an unbiased one.
                      single_candidate: crm_linked plus an inferred link when
                      the event reaches exactly one deal. account_associated:
                      every link. The response reports the comparison under all
                      four (acrossLinkScopes), so you can see whether the
                      direction holds.
                  observed:
                    type: object
                    properties:
                      higher:
                        type: string
                        nullable: true
                        enum:
                          - cohortA
                          - cohortB
                          - equal
                          - null
                        description: >-
                          Which side has the higher rate on the compared
                          outcome. 'Higher' is not 'better' for every outcome.
                          Null when a side has no deal with a readable outcome.
                      gapPoints:
                        type: number
                        nullable: true
                        description: >-
                          cohortA rate minus cohortB rate, in percentage points
                          (12.5 = twelve and a half points). Null when a side
                          has no readable deals — never 0.
                      unavailableReason:
                        type: string
                        nullable: true
                        enum:
                          - no_readable_deals_in_cohort_a
                          - no_readable_deals_in_cohort_b
                          - null
                      summary:
                        type: string
                        description: >-
                          The observation in one sentence, with the exact
                          counts. Safe to report as what happened in these
                          deals.
                    required:
                      - higher
                      - gapPoints
                      - unavailableReason
                      - summary
                    description: >-
                      The descriptive result. ALWAYS reportable, in every
                      verdict state: say which side is higher, by how much and
                      on how many deals. It needs no significance test. What the
                      verdict adds is how far you may go beyond these deals.
                  exclusions:
                    type: object
                    properties:
                      postOutcomeOnly:
                        type: integer
                        description: >-
                          Closed deals whose matching conversations all happened
                          after the deal closed. A topic discussed during
                          onboarding is not evidence about the sale.
                      orderUnknown:
                        type: integer
                        description: >-
                          Closed deals where no matching conversation can be
                          shown to precede the close: the close time is only a
                          date and the conversation fell on it, or the close was
                          detected by sync (so its recorded time trails the real
                          one) and the conversation fell inside that allowance,
                          or the deal has no close date at all.
                      reopened:
                        type: integer
                        description: >-
                          Closed deals that closed, reopened and closed again.
                          Only a first sales episode is measured, so these are
                          left out rather than paired with the wrong episode's
                          conversations.
                      ambiguousExposure:
                        type: integer
                        description: >-
                          Deals left out of BOTH sides because they match the
                          other cohort only through a looser link than the
                          chosen scope — their exposure is unclear, so they
                          belong in neither arm.
                    required:
                      - postOutcomeOnly
                      - orderUnknown
                      - reopened
                      - ambiguousExposure
                    description: >-
                      Deals that matched but were not compared, by reason. Each
                      deal is counted under one reason.
                  membershipBasis:
                    type: object
                    properties:
                      open:
                        type: integer
                        description: 'Still open: there is no close to precede.'
                      crmRecordedClose:
                        type: integer
                        description: >-
                          Ordered against a close time the CRM recorded. Known
                          order.
                      syncDetectedCloseAssumed:
                        type: integer
                        description: >-
                          Ordered against a close Octave detected during sync,
                          which is recorded later than the real close by an
                          unknown amount. These deals count as pre-close ONLY
                          under the sync-lag assumption (syncLagAllowanceDays):
                          an outage or a backfill can exceed it.
                      dateOnlyClose:
                        type: integer
                        description: >-
                          Ordered by calendar day against a close date with no
                          time. Days are compared in UTC — a convention, not the
                          CRM's own calendar day.
                      syncLagAllowanceDays:
                        type: integer
                    required:
                      - open
                      - crmRecordedClose
                      - syncDetectedCloseAssumed
                      - dateOnlyClose
                      - syncLagAllowanceDays
                    description: >-
                      How the compared deals were shown to have a conversation
                      before their outcome, as counts of deals. When most rest
                      on the sync-lag assumption, read timingSensitivity.
                  timingSensitivity:
                    type: object
                    properties:
                      cohortA:
                        type: object
                        properties:
                          deals:
                            type: integer
                          readable:
                            type: integer
                          successes:
                            type: integer
                          rate:
                            type: number
                            nullable: true
                        required:
                          - deals
                          - readable
                          - successes
                          - rate
                      cohortB:
                        type: object
                        properties:
                          deals:
                            type: integer
                          readable:
                            type: integer
                          successes:
                            type: integer
                          rate:
                            type: number
                            nullable: true
                        required:
                          - deals
                          - readable
                          - successes
                          - rate
                      gapPoints:
                        type: number
                        nullable: true
                      higher:
                        type: string
                        nullable: true
                        enum:
                          - cohortA
                          - cohortB
                          - equal
                          - null
                      directionAgrees:
                        type: boolean
                        nullable: true
                        description: >-
                          Whether the strict-timing comparison puts the same
                          side higher as the main one. Null when either has no
                          readable gap.
                    required:
                      - cohortA
                      - cohortB
                      - gapPoints
                      - higher
                      - directionAgrees
                    description: >-
                      The same comparison keeping only deals whose order is
                      KNOWN: still open, or closed at a time the CRM recorded.
                      It drops every deal admitted under the sync-lag assumption
                      or a date-only close, so it is smaller. If the direction
                      changes here, the main result rests on an assumption about
                      timing — say so.
                  acrossLinkScopes:
                    type: object
                    properties:
                      scopes:
                        type: array
                        items:
                          type: object
                          properties:
                            linkScope:
                              type: string
                              enum:
                                - crm_linked
                                - single_candidate
                                - outcome_attribution
                                - account_associated
                            cohortA:
                              type: object
                              properties:
                                deals:
                                  type: integer
                                readable:
                                  type: integer
                                successes:
                                  type: integer
                                rate:
                                  type: number
                                  nullable: true
                              required:
                                - deals
                                - readable
                                - successes
                                - rate
                            cohortB:
                              type: object
                              properties:
                                deals:
                                  type: integer
                                readable:
                                  type: integer
                                successes:
                                  type: integer
                                rate:
                                  type: number
                                  nullable: true
                              required:
                                - deals
                                - readable
                                - successes
                                - rate
                            gapPoints:
                              type: number
                              nullable: true
                            higher:
                              type: string
                              nullable: true
                              enum:
                                - cohortA
                                - cohortB
                                - equal
                                - null
                          required:
                            - linkScope
                            - cohortA
                            - cohortB
                            - gapPoints
                            - higher
                      directionAgrees:
                        type: boolean
                        nullable: true
                        description: >-
                          Whether every scope with a readable gap puts the same
                          side higher. False means the answer depends on how
                          firmly conversations are tied to deals — say so. Null
                          when fewer than two scopes have a gap.
                    required:
                      - scopes
                      - directionAgrees
                    description: >-
                      The same comparison under each link scope, firmest first.
                      A firmer scope is a smaller and differently selected
                      population, not simply a more correct one: deals a rep
                      attaches activity to in the CRM are not a random sample,
                      and the direction of that difference is not stable.
                  cohortA:
                    type: object
                    properties:
                      label:
                        type: string
                      deals:
                        type: integer
                        description: >-
                          Distinct CRM deals with at least one matching event in
                          the window.
                      wonDeals:
                        type: integer
                      lostDeals:
                        type: integer
                      openDeals:
                        type: integer
                        description: >-
                          Still open — counted in `deals`, never in the win
                          rate.
                      winRate:
                        type: object
                        properties:
                          closedDeals:
                            type: integer
                            description: >-
                              Won + lost deals behind the rate. Open deals are
                              not in it.
                          rate:
                            type: number
                            nullable: true
                            description: >-
                              won / closedDeals, 0..1; null with no closed
                              deals.
                          low:
                            type: number
                            nullable: true
                            description: 95% interval, lower bound.
                          high:
                            type: number
                            nullable: true
                            description: 95% interval, upper bound.
                          sampleSizeBand:
                            type: string
                            enum:
                              - insufficient
                              - low
                              - medium
                              - high
                            description: >-
                              Sample-size band only; not confidence in
                              attribution, product alignment, or causality:
                              insufficient (<3 closed deals — do not quote the
                              rate), low (<5), medium (<15), high. Two rates
                              whose intervals overlap heavily are not
                              distinguishable, whatever their point values.
                        required:
                          - closedDeals
                          - rate
                          - low
                          - high
                          - sampleSizeBand
                        description: >-
                          A win rate with its 95% Wilson interval and sample
                          size. Quote the interval, not just the rate, when the
                          sample is small.
                      knownWonValue:
                        type: number
                        nullable: true
                        description: >-
                          Sum of the home-currency values of the won deals whose
                          value is KNOWN and not negative. NOT revenue and not a
                          total for the side: read it with wonDealsWithValue,
                          and see wonDealsValueMissing, wonDealsValueUnconverted
                          and negativeValueWonDeals for what it leaves out. Null
                          — never 0 — when no won deal has a known value. It
                          differs from the Insights won-amount figure, which
                          counts unknown values as 0 and nets negative ones.
                      wonDealsWithValue:
                        type: integer
                        description: >-
                          Won deals with a known, non-negative home-currency
                          value, a genuine zero included. When this is below
                          wonDeals, wonAmount is incomplete.
                      wonDealsValueMissing:
                        type: integer
                        description: Won deals whose CRM value field is empty.
                      wonDealsValueUnconverted:
                        type: integer
                        description: >-
                          Won deals that have a CRM value but no home-currency
                          one: it could not be converted.
                      negativeValueWonDeals:
                        type: object
                        properties:
                          deals:
                            type: integer
                          amount:
                            type: number
                        required:
                          - deals
                          - amount
                        description: >-
                          Won deals carrying a negative value, and their sum.
                          Kept out of knownWonValue rather than netted into it —
                          a change of measure, stated here so it is not silent.
                          A negative value can be a legitimate adjustment (a CRM
                          amount field that records a change in contract value),
                          not a bad record.
                      medianWonDealSize:
                        type: number
                        nullable: true
                        description: >-
                          Median over the same deals as knownWonValue (known,
                          non-negative values, a genuine zero included). Median,
                          not mean: one outsized deal does not move it.
                      outcome:
                        type: object
                        properties:
                          successes:
                            type: integer
                          failures:
                            type: integer
                          notObservable:
                            type: integer
                            description: >-
                              Deals the outcome cannot be read for yet, or at
                              all (see definition.exclusions). In `deals`, never
                              in the rate.
                          notObservableReasons:
                            type: object
                            properties:
                              deal_still_open:
                                type: integer
                              window_not_elapsed:
                                type: integer
                              stay_not_yet_longer_than_median:
                                type: integer
                              no_open_stage_on_record_at_anchor:
                                type: integer
                              no_open_stage_or_no_dependable_median:
                                type: integer
                              no_scored_follow_up:
                                type: integer
                            description: >-
                              notObservable split by reason; the counts add up
                              to it. deal_still_open, window_not_elapsed and
                              stay_not_yet_longer_than_median resolve by
                              waiting. no_open_stage_on_record_at_anchor,
                              no_open_stage_or_no_dependable_median and
                              no_scored_follow_up are missing data: waiting does
                              not fix them.
                          rate:
                            type: object
                            properties:
                              closedDeals:
                                type: integer
                                description: >-
                                  Won + lost deals behind the rate. Open deals
                                  are not in it.
                              rate:
                                type: number
                                nullable: true
                                description: >-
                                  won / closedDeals, 0..1; null with no closed
                                  deals.
                              low:
                                type: number
                                nullable: true
                                description: 95% interval, lower bound.
                              high:
                                type: number
                                nullable: true
                                description: 95% interval, upper bound.
                              sampleSizeBand:
                                type: string
                                enum:
                                  - insufficient
                                  - low
                                  - medium
                                  - high
                                description: >-
                                  Sample-size band only; not confidence in
                                  attribution, product alignment, or causality:
                                  insufficient (<3 closed deals — do not quote
                                  the rate), low (<5), medium (<15), high. Two
                                  rates whose intervals overlap heavily are not
                                  distinguishable, whatever their point values.
                            required:
                              - closedDeals
                              - rate
                              - low
                              - high
                              - sampleSizeBand
                            description: >-
                              successes / (successes + failures) with its 95%
                              interval. Here `closedDeals` is the number of
                              deals with an observable outcome; for win_rate
                              that is the closed deals and this equals
                              `winRate`.
                        required:
                          - successes
                          - failures
                          - notObservable
                          - notObservableReasons
                          - rate
                        description: >-
                          This side on the outcome being compared. `difference`
                          and `verdict` are about this rate.
                    required:
                      - label
                      - deals
                      - wonDeals
                      - lostDeals
                      - openDeals
                      - winRate
                      - knownWonValue
                      - wonDealsWithValue
                      - wonDealsValueMissing
                      - wonDealsValueUnconverted
                      - negativeValueWonDeals
                      - medianWonDealSize
                      - outcome
                  cohortB:
                    type: object
                    properties:
                      label:
                        type: string
                      deals:
                        type: integer
                        description: >-
                          Distinct CRM deals with at least one matching event in
                          the window.
                      wonDeals:
                        type: integer
                      lostDeals:
                        type: integer
                      openDeals:
                        type: integer
                        description: >-
                          Still open — counted in `deals`, never in the win
                          rate.
                      winRate:
                        type: object
                        properties:
                          closedDeals:
                            type: integer
                            description: >-
                              Won + lost deals behind the rate. Open deals are
                              not in it.
                          rate:
                            type: number
                            nullable: true
                            description: >-
                              won / closedDeals, 0..1; null with no closed
                              deals.
                          low:
                            type: number
                            nullable: true
                            description: 95% interval, lower bound.
                          high:
                            type: number
                            nullable: true
                            description: 95% interval, upper bound.
                          sampleSizeBand:
                            type: string
                            enum:
                              - insufficient
                              - low
                              - medium
                              - high
                            description: >-
                              Sample-size band only; not confidence in
                              attribution, product alignment, or causality:
                              insufficient (<3 closed deals — do not quote the
                              rate), low (<5), medium (<15), high. Two rates
                              whose intervals overlap heavily are not
                              distinguishable, whatever their point values.
                        required:
                          - closedDeals
                          - rate
                          - low
                          - high
                          - sampleSizeBand
                        description: >-
                          A win rate with its 95% Wilson interval and sample
                          size. Quote the interval, not just the rate, when the
                          sample is small.
                      knownWonValue:
                        type: number
                        nullable: true
                        description: >-
                          Sum of the home-currency values of the won deals whose
                          value is KNOWN and not negative. NOT revenue and not a
                          total for the side: read it with wonDealsWithValue,
                          and see wonDealsValueMissing, wonDealsValueUnconverted
                          and negativeValueWonDeals for what it leaves out. Null
                          — never 0 — when no won deal has a known value. It
                          differs from the Insights won-amount figure, which
                          counts unknown values as 0 and nets negative ones.
                      wonDealsWithValue:
                        type: integer
                        description: >-
                          Won deals with a known, non-negative home-currency
                          value, a genuine zero included. When this is below
                          wonDeals, wonAmount is incomplete.
                      wonDealsValueMissing:
                        type: integer
                        description: Won deals whose CRM value field is empty.
                      wonDealsValueUnconverted:
                        type: integer
                        description: >-
                          Won deals that have a CRM value but no home-currency
                          one: it could not be converted.
                      negativeValueWonDeals:
                        type: object
                        properties:
                          deals:
                            type: integer
                          amount:
                            type: number
                        required:
                          - deals
                          - amount
                        description: >-
                          Won deals carrying a negative value, and their sum.
                          Kept out of knownWonValue rather than netted into it —
                          a change of measure, stated here so it is not silent.
                          A negative value can be a legitimate adjustment (a CRM
                          amount field that records a change in contract value),
                          not a bad record.
                      medianWonDealSize:
                        type: number
                        nullable: true
                        description: >-
                          Median over the same deals as knownWonValue (known,
                          non-negative values, a genuine zero included). Median,
                          not mean: one outsized deal does not move it.
                      outcome:
                        type: object
                        properties:
                          successes:
                            type: integer
                          failures:
                            type: integer
                          notObservable:
                            type: integer
                            description: >-
                              Deals the outcome cannot be read for yet, or at
                              all (see definition.exclusions). In `deals`, never
                              in the rate.
                          notObservableReasons:
                            type: object
                            properties:
                              deal_still_open:
                                type: integer
                              window_not_elapsed:
                                type: integer
                              stay_not_yet_longer_than_median:
                                type: integer
                              no_open_stage_on_record_at_anchor:
                                type: integer
                              no_open_stage_or_no_dependable_median:
                                type: integer
                              no_scored_follow_up:
                                type: integer
                            description: >-
                              notObservable split by reason; the counts add up
                              to it. deal_still_open, window_not_elapsed and
                              stay_not_yet_longer_than_median resolve by
                              waiting. no_open_stage_on_record_at_anchor,
                              no_open_stage_or_no_dependable_median and
                              no_scored_follow_up are missing data: waiting does
                              not fix them.
                          rate:
                            type: object
                            properties:
                              closedDeals:
                                type: integer
                                description: >-
                                  Won + lost deals behind the rate. Open deals
                                  are not in it.
                              rate:
                                type: number
                                nullable: true
                                description: >-
                                  won / closedDeals, 0..1; null with no closed
                                  deals.
                              low:
                                type: number
                                nullable: true
                                description: 95% interval, lower bound.
                              high:
                                type: number
                                nullable: true
                                description: 95% interval, upper bound.
                              sampleSizeBand:
                                type: string
                                enum:
                                  - insufficient
                                  - low
                                  - medium
                                  - high
                                description: >-
                                  Sample-size band only; not confidence in
                                  attribution, product alignment, or causality:
                                  insufficient (<3 closed deals — do not quote
                                  the rate), low (<5), medium (<15), high. Two
                                  rates whose intervals overlap heavily are not
                                  distinguishable, whatever their point values.
                            required:
                              - closedDeals
                              - rate
                              - low
                              - high
                              - sampleSizeBand
                            description: >-
                              successes / (successes + failures) with its 95%
                              interval. Here `closedDeals` is the number of
                              deals with an observable outcome; for win_rate
                              that is the closed deals and this equals
                              `winRate`.
                        required:
                          - successes
                          - failures
                          - notObservable
                          - notObservableReasons
                          - rate
                        description: >-
                          This side on the outcome being compared. `difference`
                          and `verdict` are about this rate.
                    required:
                      - label
                      - deals
                      - wonDeals
                      - lostDeals
                      - openDeals
                      - winRate
                      - knownWonValue
                      - wonDealsWithValue
                      - wonDealsValueMissing
                      - wonDealsValueUnconverted
                      - negativeValueWonDeals
                      - medianWonDealSize
                      - outcome
                  overlappingDeals:
                    type: integer
                    description: >-
                      Deals that matched BOTH cohorts. They are left out of both
                      arms so the two samples are independent; always 0 when
                      cohort B is 'everything else'.
                  difference:
                    type: object
                    properties:
                      points:
                        type: number
                        nullable: true
                        description: >-
                          cohortA outcome rate minus cohortB outcome rate, as a
                          fraction (0.12 = 12 points).
                      low:
                        type: number
                        nullable: true
                      high:
                        type: number
                        nullable: true
                      ratio:
                        type: number
                        nullable: true
                        description: cohortA outcome rate / cohortB outcome rate.
                      pValue:
                        type: number
                        nullable: true
                      adjustedPValue:
                        type: number
                        nullable: true
                        description: >-
                          pValue corrected for `comparisonsDeclared`. The
                          verdict is based on this one.
                      comparisonsDeclared:
                        type: integer
                      test:
                        type: string
                        nullable: true
                        enum:
                          - fisher_exact
                          - two_proportion_z
                          - null
                    required:
                      - points
                      - low
                      - high
                      - ratio
                      - pValue
                      - adjustedPValue
                      - comparisonsDeclared
                      - test
                    description: >-
                      The gap between the two sides on the compared outcome,
                      with a 95% interval.
                  verdict:
                    type: object
                    properties:
                      state:
                        type: string
                        enum:
                          - insufficient_evidence
                          - no_material_difference
                          - difference_to_watch
                          - difference_to_investigate
                        description: >-
                          How far the observed difference can be taken beyond
                          these deals. It never decides whether to report
                          `observed`. insufficient_evidence: report the observed
                          direction as directional or early, with its counts; do
                          not present it as a general pattern. `uncertainty`
                          says why, and what would help. no_material_difference:
                          enough data to rule out a gap of the declared margin
                          either way — the two perform alike.
                          difference_to_watch: leans one way without clearing
                          the bar — a lead; a cheap, reversible test is
                          proportionate. difference_to_investigate: survives
                          correction for the comparisons made — state it with
                          its interval and look for the reason. The interval and
                          p-value measure sampling noise only. Selection (which
                          deals got linked), missing coverage and confounding
                          are separate, and a small p-value does not remove
                          them.
                      uncertainty:
                        type: string
                        nullable: true
                        enum:
                          - small_sample
                          - immature_outcomes
                          - low_coverage
                          - null
                        description: >-
                          Set when state is insufficient_evidence or
                          difference_to_watch. small_sample: too few readable
                          deals — say it is directional, suggest a reversible
                          test. immature_outcomes: most deals cannot be read yet
                          — say it is early and when to look again.
                          low_coverage: a material share of the evidence is
                          missing — say what is missing.
                      claimLevel:
                        type: string
                        enum:
                          - observed
                          - compared
                          - associated
                        description: >-
                          The strongest wording this supports. observed: quote
                          counts and rates only, no 'more' or 'less'. compared:
                          'A won more often than B', with the interval.
                          associated: 'X is associated with winning'. Never
                          'drives', 'causes' or 'because': these cohorts were
                          not assigned at random.
                      summary:
                        type: string
                        description: One plain sentence stating the verdict and why.
                    required:
                      - state
                      - uncertainty
                      - claimLevel
                      - summary
                  sampleNeeded:
                    type: object
                    properties:
                      dealsPerCohort:
                        type: integer
                        nullable: true
                      smallerCohortHas:
                        type: integer
                    required:
                      - dealsPerCohort
                      - smallerCohortHas
                    description: >-
                      Deals with an observable outcome (closed deals, for
                      win_rate) EACH cohort would need to confirm a gap of the
                      size observed (95% confidence, 80% power), next to what
                      the smaller cohort has. When the evidence is insufficient
                      this says how far away an answer is.
                  stratified:
                    type: object
                    nullable: true
                    properties:
                      by:
                        type: string
                      strata:
                        type: array
                        items:
                          type: object
                          properties:
                            key:
                              type: string
                            name:
                              type: string
                            cohortA:
                              type: object
                              properties:
                                closedDeals:
                                  type: integer
                                  description: >-
                                    Won + lost deals behind the rate. Open deals
                                    are not in it.
                                rate:
                                  type: number
                                  nullable: true
                                  description: >-
                                    won / closedDeals, 0..1; null with no closed
                                    deals.
                                low:
                                  type: number
                                  nullable: true
                                  description: 95% interval, lower bound.
                                high:
                                  type: number
                                  nullable: true
                                  description: 95% interval, upper bound.
                                sampleSizeBand:
                                  type: string
                                  enum:
                                    - insufficient
                                    - low
                                    - medium
                                    - high
                                  description: >-
                                    Sample-size band only; not confidence in
                                    attribution, product alignment, or
                                    causality: insufficient (<3 closed deals —
                                    do not quote the rate), low (<5), medium
                                    (<15), high. Two rates whose intervals
                                    overlap heavily are not distinguishable,
                                    whatever their point values.
                              required:
                                - closedDeals
                                - rate
                                - low
                                - high
                                - sampleSizeBand
                              description: >-
                                A win rate with its 95% Wilson interval and
                                sample size. Quote the interval, not just the
                                rate, when the sample is small.
                            cohortB:
                              type: object
                              properties:
                                closedDeals:
                                  type: integer
                                  description: >-
                                    Won + lost deals behind the rate. Open deals
                                    are not in it.
                                rate:
                                  type: number
                                  nullable: true
                                  description: >-
                                    won / closedDeals, 0..1; null with no closed
                                    deals.
                                low:
                                  type: number
                                  nullable: true
                                  description: 95% interval, lower bound.
                                high:
                                  type: number
                                  nullable: true
                                  description: 95% interval, upper bound.
                                sampleSizeBand:
                                  type: string
                                  enum:
                                    - insufficient
                                    - low
                                    - medium
                                    - high
                                  description: >-
                                    Sample-size band only; not confidence in
                                    attribution, product alignment, or
                                    causality: insufficient (<3 closed deals —
                                    do not quote the rate), low (<5), medium
                                    (<15), high. Two rates whose intervals
                                    overlap heavily are not distinguishable,
                                    whatever their point values.
                              required:
                                - closedDeals
                                - rate
                                - low
                                - high
                                - sampleSizeBand
                              description: >-
                                A win rate with its 95% Wilson interval and
                                sample size. Quote the interval, not just the
                                rate, when the sample is small.
                            differencePoints:
                              type: number
                              nullable: true
                          required:
                            - key
                            - name
                            - cohortA
                            - cohortB
                            - differencePoints
                      pooledOddsRatio:
                        type: number
                        nullable: true
                        description: >-
                          Odds of a success on the compared `outcome` (a win,
                          for win_rate), cohort A vs B, among deals in the SAME
                          stratum (Mantel–Haenszel). Above 1 favours A.
                      pValue:
                        type: number
                        nullable: true
                        description: >-
                          Pooled test, corrected for comparisonsDeclared like
                          the headline.
                      holdsWithinStrata:
                        type: string
                        enum:
                          - 'yes'
                          - same_direction_unconfirmed
                          - 'no'
                          - reverses
                          - cannot_tell
                        description: >-
                          yes: A is also ahead among like deals, and the pooled
                          test clears the corrected bar.
                          same_direction_unconfirmed: like for like the gap
                          points the same way, but the strata are too thin to
                          confirm it — this does NOT mean the mix explains the
                          gap. no: like for like the odds are close to even (or
                          lean the other way, unconfirmed) — the overall gap
                          owes more to which groups the cohorts sit in than to
                          what defines them. reverses: like for like, B is
                          ahead, and confirmed (Simpson's paradox) — do not
                          report the overall gap. cannot_tell: too few strata
                          hold both cohorts and both outcomes.
                      summary:
                        type: string
                    required:
                      - by
                      - strata
                      - pooledOddsRatio
                      - pValue
                      - holdsWithinStrata
                      - summary
                    description: >-
                      The same comparison made within each value of
                      `stratifyBy`, then pooled. Null unless stratifyBy was
                      given.
                  caveats:
                    type: array
                    items:
                      type: string
                    description: >-
                      Things about this data that limit what the numbers
                      support. Read them before quoting.
                  dataWindow:
                    type: object
                    properties:
                      kind:
                        type: string
                        enum:
                          - event_range
                          - stats_period
                      startDate:
                        type: string
                        nullable: true
                        description: >-
                          Inclusive start (ISO). Null only when no data exists
                          yet.
                      endDate:
                        type: string
                        nullable: true
                        description: >-
                          End (ISO). An event_range with no endDate given ends
                          at the time of the request.
                      isDefault:
                        type: boolean
                        description: >-
                          True when the caller did not choose this window and
                          the tool's default applied.
                      periodType:
                        type: string
                        nullable: true
                        enum:
                          - week
                          - month
                          - quarter
                          - null
                        description: >-
                          week / month / quarter for a stats_period; null
                          otherwise.
                    required:
                      - kind
                      - startDate
                      - endDate
                      - isDefault
                      - periodType
                    description: >-
                      The time span these numbers cover. Compare numbers from
                      two tools only when their dataWindow kind and dates match.
                  linkScopeSource:
                    type: string
                    enum:
                      - request
                      - workspace_default
                      - product_default
                    description: >-
                      Where `linkScope` came from: request (the caller named
                      it), workspace_default (the workspace's deal matching
                      rule, set beside its CRM mappings) or product_default
                      (outcome_attribution, when the workspace never chose). The
                      Insights win rates use the workspace's rule, so only a
                      comparison made under a `request` scope is expected to
                      differ from them.
                required:
                  - _metadata
                  - definition
                  - linkScope
                  - observed
                  - exclusions
                  - membershipBasis
                  - timingSensitivity
                  - acrossLinkScopes
                  - cohortA
                  - cohortB
                  - overlappingDeals
                  - difference
                  - verdict
                  - sampleNeeded
                  - stratified
                  - caveats
                  - dataWindow
                  - linkScopeSource
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties:
                  _metadata:
                    $ref: '#/components/schemas/Metadata'
                  message:
                    type: string
                required:
                  - _metadata
                  - message
      deprecated: false
components:
  schemas:
    Metadata:
      type: object
      properties:
        usage:
          type: number
          default: 0
          example: 0
          description: API usage
        requestId:
          type: string
          example: requestId
          description: Request ID
        message:
          type: string
          example: message
          description: Message
        timestamp:
          type: string
          example: '2021-01-01T00:00:00.000Z'
          description: Timestamp
      required:
        - requestId
        - timestamp
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api_key

````