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

# Signup cohorts

> Aggregate signup-month cohorts by overall totals, current plan, or current billing site. Requires a tenant-scoped API key and is available only for eligible organizations.

Aggregates signup-month cohorts by membership package or billing site.

<Note>This endpoint requires a tenant-scoped API key and is available only for eligible organizations.</Note>

<RequestExample>
  ```bash Overall monthly cohorts theme={null}
  curl "https://app.nautilus.co/api/v1/cohorts?start=2026-01-01&end=2026-06-30" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```bash Cohorts by current plan theme={null}
  curl "https://app.nautilus.co/api/v1/cohorts?dimension=plan&start=2026-01-01&end=2026-06-30" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```bash Cohorts by billing site theme={null}
  curl "https://app.nautilus.co/api/v1/cohorts?dimension=site&start=2026-01-01" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</RequestExample>

## Response

The response includes the applied dimension, signup-date coverage, dimension truncation metadata, and cohort rows.

```json theme={null}
{
  "organizationId": "org_example_123",
  "dateRange": {
    "start": "2026-01-01T00:00:00.000Z",
    "end": "2026-06-30T00:00:00.000Z"
  },
  "source": "membership_signup",
  "available": true,
  "dimension": "plan",
  "signupDateCoverage": {
    "includedMemberships": 1180,
    "membershipsWithoutSignupDate": 24,
    "handling": "excluded_from_cohorts"
  },
  "dimensionValues": {
    "limit": 250,
    "included": 3,
    "total": 3,
    "truncated": false
  },
  "cohorts": [
    {
      "cohortMonth": "2026-01",
      "dimensionValue": {
        "type": "plan",
        "planName": "Unlimited Plus"
      },
      "cohortSize": 240,
      "stillActive": 198,
      "churned": 42,
      "voluntary": 31,
      "involuntary": 11,
      "churnRatePct": 17.5,
      "churnWithin": {
        "days0To30": 8,
        "days31To90": 12,
        "days91To180": 16,
        "days181To365": 6,
        "days365Plus": 0,
        "unknown": 0
      }
    }
  ]
}
```

## Dimensions

`dimension=none` returns one row per signup month.

`dimension=plan` groups by the membership's current POS plan name.

`dimension=site` groups by the membership's current billing site code and resolved site name.

For `plan` and `site`, Nautilus returns up to 250 dimension values for the requested range. Check `dimensionValues.truncated` to see whether lower-volume values were omitted.

## Caveats

Memberships without signup dates are excluded from cohort rows and counted in `signupDateCoverage.membershipsWithoutSignupDate`.

The plan and site dimensions use current recurring-account values, not signup-time values. Historical cohort composition can shift when a member changes plan or billing site.

There is no normalized promotion or source cohort dimension in the current response.

## Errors

* **400** - Invalid dimension or cohort analytics are not available for this organization.
* **401** - Missing, invalid, or non-tenant-scoped API key.
* **500** - Internal server error.


## OpenAPI

````yaml GET /api/v1/cohorts
openapi: 3.1.0
info:
  title: Nautilus Public API
  version: 1.0.0
  description: >-
    Tenant-scoped public API. Except for /api/v1/openapi.json, requests use a
    Clerk tenant API key as a Bearer token. The key's organizationId is the sole
    tenant scope; organization IDs supplied by callers are never accepted.
    Detail endpoints deliberately return 404 for both missing and cross-tenant
    records. Canonical collections use the standard envelope and endpoint-bound
    cursor pagination. Timestamps are UTC ISO 8601 values and monetary amounts
    ending in Cents are integer cents. Responses use narrow serializers and
    exclude credentials, API keys, provider configuration, access tokens,
    webhook secrets, raw provider payloads, and internal workflow or activity
    data.
servers:
  - url: https://app.nautilus.co
security:
  - tenantApiKey: []
tags:
  - name: Contract
  - name: Cancellations
  - name: Sites
  - name: Products
  - name: Checkout links
  - name: Purchases
  - name: Contact lists
  - name: Contacts
  - name: Marketing
  - name: Forms
  - name: Vouchers
  - name: Links
  - name: Automations
  - name: Surveys
  - name: Cases
  - name: Sonny's POS
  - name: Analytics
  - name: Messaging
  - name: Legacy
    description: Deprecated noncanonical endpoints retained for compatibility.
paths:
  /api/v1/cohorts:
    get:
      tags:
        - Analytics
        - Legacy
      summary: Signup cohorts
      description: >-
        Aggregate signup-month cohorts by overall totals, current plan, or
        current billing site. Requires a tenant-scoped API key and is available
        only for eligible organizations.
      operationId: listCohorts
      parameters:
        - name: start
          in: query
          required: false
          schema:
            type: string
          description: >-
            Inclusive lower bound on cohort month. The value is truncated to its
            month.
        - name: end
          in: query
          required: false
          schema:
            type: string
          description: >-
            Inclusive upper bound on cohort month. The value is truncated to its
            month.
        - name: dimension
          in: query
          required: false
          schema:
            type: string
            enum:
              - none
              - plan
              - site
            default: none
          description: Dimension used to group cohort rows.
      responses:
        '200':
          description: Cohort analytics response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CohortsResponse'
        '400':
          description: >-
            Invalid dimension or cohort analytics are not available for this
            organization
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalidDimension:
                  value:
                    error: 'Invalid dimension. Use one of: none, plan, site'
                unsupportedOrganization:
                  value:
                    error: Cohort analytics are not available for this organization
        '401':
          description: Missing, invalid, or non-tenant-scoped API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      deprecated: true
components:
  schemas:
    CohortsResponse:
      type: object
      required:
        - organizationId
        - dateRange
        - source
        - available
        - dimension
        - signupDateCoverage
        - dimensionValues
        - cohorts
      properties:
        organizationId:
          type: string
        dateRange:
          $ref: '#/components/schemas/DateRange'
        source:
          type: string
          const: membership_signup
        available:
          type: boolean
          const: true
        dimension:
          type: string
          enum:
            - none
            - plan
            - site
        signupDateCoverage:
          type: object
          required:
            - includedMemberships
            - membershipsWithoutSignupDate
            - handling
          properties:
            includedMemberships:
              type: integer
            membershipsWithoutSignupDate:
              type: integer
            handling:
              type: string
              const: excluded_from_cohorts
        dimensionValues:
          type: object
          required:
            - limit
            - included
            - total
            - truncated
          properties:
            limit:
              type:
                - integer
                - 'null'
            included:
              type: integer
            total:
              type: integer
            truncated:
              type: boolean
        cohorts:
          type: array
          items:
            $ref: '#/components/schemas/CohortRow'
    Error:
      type: object
      additionalProperties: false
      properties:
        error:
          type: string
      required:
        - error
    DateRange:
      type: object
      title: Date range
      required:
        - start
        - end
      properties:
        start:
          type:
            - string
            - 'null'
          format: date-time
          description: Parsed `start` filter, or null when omitted.
        end:
          type:
            - string
            - 'null'
          format: date-time
          description: Parsed `end` filter, or null when omitted.
    CohortRow:
      type: object
      required:
        - cohortMonth
        - dimensionValue
        - cohortSize
        - stillActive
        - churned
        - voluntary
        - involuntary
        - churnRatePct
        - churnWithin
      properties:
        cohortMonth:
          type: string
          description: Signup cohort month in `YYYY-MM` format.
        dimensionValue:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/PlanDimensionValue'
            - $ref: '#/components/schemas/SiteDimensionValue'
        cohortSize:
          type: integer
        stillActive:
          type: integer
        churned:
          type: integer
        voluntary:
          type: integer
        involuntary:
          type: integer
        churnRatePct:
          type: number
        churnWithin:
          $ref: '#/components/schemas/ChurnWithin'
    PlanDimensionValue:
      type: object
      required:
        - type
        - planName
      properties:
        type:
          type: string
          const: plan
        planName:
          type:
            - string
            - 'null'
    SiteDimensionValue:
      type: object
      required:
        - type
        - siteCode
        - siteName
      properties:
        type:
          type: string
          const: site
        siteCode:
          type:
            - string
            - 'null'
        siteName:
          type:
            - string
            - 'null'
    ChurnWithin:
      type: object
      required:
        - days0To30
        - days31To90
        - days91To180
        - days181To365
        - days365Plus
        - unknown
      properties:
        days0To30:
          type: integer
        days31To90:
          type: integer
        days91To180:
          type: integer
        days181To365:
          type: integer
        days365Plus:
          type: integer
        unknown:
          type: integer
  securitySchemes:
    tenantApiKey:
      type: http
      scheme: bearer
      bearerFormat: Clerk tenant API key
      description: >-
        Clerk tenant API key. The organizationId encoded by the key is the exact
        and only tenant scope.

````