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

# Revenue report for a period

> What the organization earned over a period, and from what, where and how it compares - in one request rather than a walk of the transactions list.

Revenue is recognised ex-tax on the day of the sale, on the organization's own clock, net of refunds and of anything Wallet credit paid for. `collected` is the part of it already paid, on the same basis, so `uncollected` is what the period sold that has not been paid yet. These are the figures of the admin's daily revenue chart for the same days.

The period is compared with the same number of days just before it (`compare=previous_period`, the default) or the same dates a year earlier (`previous_year`); every breakdown row then carries its revenue in that period and the change, and `movers` lists the streams, clubs and items that moved most. Breakdowns: by revenue stream (bookings, memberships, passes, drop-ins, products, other), by club (unless `clubId` narrows the report to one), by the payment method that collected the money, and the top items sold (a class or court, a plan, a product). `trend` buckets the period by day, week (starting Monday) or month - by default a month or less by day, up to six months by week, anything longer by month.

Amounts are in the organization's `currency`. A period may span at most 366 days. Reports have their own limit of 20 requests a minute, on top of the platform's.




## OpenAPI

````yaml /openapi-platform.json get /v1/platform/reports/revenue
openapi: 3.0.0
info:
  title: 1club Platform API
  version: 1.0.0
  description: >-
    The 1club Platform API lets you programmatically access and manage your
    organization's data.


    ## Official API Contract


    This documentation is the official source of truth for the 1club Platform
    API.

    If an integration relies on undocumented endpoints, fields, response shapes,
    or internal behavior outside this spec, we can't guarantee backward
    compatibility.

    Build against what's documented here to stay stable as the platform evolves.


    ## Authentication


    All requests require a customer API key passed as a Bearer token:


    ```

    Authorization: Bearer 1club_sk_live_...

    ```


    Generate API keys from the admin portal under **Settings > API Tokens**.

    The key is tied to your organization - all responses are scoped to your
    org's data.


    ## Rate Limiting


    - **100 requests per minute** per API key

    - When exceeded, the API returns `429 Too Many Requests` with a
    `Retry-After` header

    - Rate limit headers are included in every response:
      - `X-RateLimit-Limit` - max requests per window
      - `X-RateLimit-Remaining` - requests remaining
      - `X-RateLimit-Reset` - seconds until the window resets

    ## Errors


    | Status | Meaning |

    |--------|---------|

    | `400` | Invalid request parameters |

    | `401` | Missing or invalid API key |

    | `404` | Resource not found (or doesn't belong to your organization) |

    | `429` | Rate limit exceeded |

    | `500` | Internal server error |
  contact:
    name: 1club API Support
    email: support@1club.ai
servers:
  - url: https://api.1club.ai
    description: Production API
security:
  - customerApiAuth: []
tags: []
paths:
  /v1/platform/reports/revenue:
    get:
      tags:
        - Reports
      summary: Revenue report for a period
      description: >
        What the organization earned over a period, and from what, where and how
        it compares - in one request rather than a walk of the transactions
        list.


        Revenue is recognised ex-tax on the day of the sale, on the
        organization's own clock, net of refunds and of anything Wallet credit
        paid for. `collected` is the part of it already paid, on the same basis,
        so `uncollected` is what the period sold that has not been paid yet.
        These are the figures of the admin's daily revenue chart for the same
        days.


        The period is compared with the same number of days just before it
        (`compare=previous_period`, the default) or the same dates a year
        earlier (`previous_year`); every breakdown row then carries its revenue
        in that period and the change, and `movers` lists the streams, clubs and
        items that moved most. Breakdowns: by revenue stream (bookings,
        memberships, passes, drop-ins, products, other), by club (unless
        `clubId` narrows the report to one), by the payment method that
        collected the money, and the top items sold (a class or court, a plan, a
        product). `trend` buckets the period by day, week (starting Monday) or
        month - by default a month or less by day, up to six months by week,
        anything longer by month.


        Amounts are in the organization's `currency`. A period may span at most
        366 days. Reports have their own limit of 20 requests a minute, on top
        of the platform's.
      parameters:
        - in: query
          name: from
          required: true
          schema:
            type: string
            format: date
          description: First day of the period (`YYYY-MM-DD`), on the organization's clock.
        - in: query
          name: to
          required: true
          schema:
            type: string
            format: date
          description: Last day of the period, inclusive.
        - in: query
          name: clubId
          schema:
            type: integer
          description: >-
            Only the revenue of this club - its bookings, plans, check-ins and
            the sales rung up there.
        - in: query
          name: billingEntityId
          schema:
            type: integer
          description: >-
            Only the revenue of this selling company, for an organization that
            trades through more than one.
        - in: query
          name: compare
          schema:
            type: string
            enum:
              - previous_period
              - previous_year
              - none
            default: previous_period
          description: What to compare the period with.
        - in: query
          name: granularity
          schema:
            type: string
            enum:
              - day
              - week
              - month
          description: >-
            How `trend` buckets the period. Chosen from the period's length when
            omitted.
        - in: query
          name: topItems
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 10
          description: How many items `topItems` lists.
      responses:
        '200':
          description: The revenue report
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformRevenueReport'
        '400':
          $ref: '#/components/responses/PlatformBadRequest'
        '401':
          $ref: '#/components/responses/PlatformUnauthorized'
        '403':
          description: API key is missing the required `transactions:read` scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformError'
        '429':
          $ref: '#/components/responses/PlatformRateLimited'
      security:
        - customerApiAuth: []
components:
  schemas:
    PlatformRevenueReport:
      type: object
      properties:
        period:
          type: object
          properties:
            from:
              type: string
              format: date
            to:
              type: string
              format: date
            days:
              type: integer
        timezone:
          type: string
          description: The clock the days are read on.
        currency:
          type: string
        totals:
          $ref: '#/components/schemas/PlatformRevenueFigures'
        comparison:
          type: object
          nullable: true
          properties:
            kind:
              type: string
              enum:
                - previous_period
                - previous_year
            period:
              type: object
              properties:
                from:
                  type: string
                  format: date
                to:
                  type: string
                  format: date
            totals:
              $ref: '#/components/schemas/PlatformRevenueFigures'
            change:
              type: object
              properties:
                revenue:
                  $ref: '#/components/schemas/PlatformRevenueChange'
                collected:
                  $ref: '#/components/schemas/PlatformRevenueChange'
                sales:
                  $ref: '#/components/schemas/PlatformRevenueChange'
        byStream:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/PlatformRevenueBreakdown'
              - type: object
                properties:
                  stream:
                    type: string
                    enum:
                      - bookings
                      - memberships
                      - passes
                      - drop_ins
                      - products
                      - other
        byClub:
          type: array
          description: Absent when the report is narrowed to one club.
          items:
            allOf:
              - $ref: '#/components/schemas/PlatformRevenueBreakdown'
              - type: object
                properties:
                  clubId:
                    type: integer
                    nullable: true
                  clubName:
                    type: string
                    nullable: true
        byPaymentMethod:
          type: array
          description: >-
            What collected the money. A sale paid by several methods counts
            under the one that paid most; 'Unattributed' is collected with no
            real-money payment behind it.
          items:
            type: object
            properties:
              method:
                type: string
              channel:
                type: string
                nullable: true
              collected:
                type: number
              share:
                type: number
        topItems:
          type: array
          description: 'What sold most: a class or court, a plan, a product.'
          items:
            allOf:
              - $ref: '#/components/schemas/PlatformRevenueBreakdown'
              - type: object
                properties:
                  stream:
                    type: string
                  label:
                    type: string
        trend:
          type: object
          properties:
            granularity:
              type: string
              enum:
                - day
                - week
                - month
            points:
              type: array
              items:
                type: object
                properties:
                  start:
                    type: string
                    format: date
                  revenue:
                    type: number
                  collected:
                    type: number
                  sales:
                    type: integer
        movers:
          type: array
          description: >-
            The streams, clubs and items whose revenue moved most against the
            comparison period, largest move first. Empty without a comparison.
          items:
            type: object
            properties:
              dimension:
                type: string
                enum:
                  - stream
                  - club
                  - item
              label:
                type: string
              revenue:
                type: number
              previousRevenue:
                type: number
              change:
                $ref: '#/components/schemas/PlatformRevenueChange'
    PlatformError:
      type: object
      properties:
        error:
          type: string
        code:
          type: string
          description: >-
            A stable, machine-readable reason, when the error has one (e.g.
            `CONTACT_EXISTS`).
        details:
          type: object
          additionalProperties: true
          description: >-
            Structured values behind the error. A 409 naming an existing record
            carries its id here, e.g. `contactId`.
    PlatformRevenueFigures:
      type: object
      properties:
        revenue:
          type: number
          description: Recognised ex-tax, net of refunds and Wallet-funded parts.
        collected:
          type: number
          description: The part of it already paid, on the same basis.
        uncollected:
          type: number
        collectionRate:
          type: number
          nullable: true
          description: '`collected / revenue`, 0-1.'
        sales:
          type: integer
        averageSale:
          type: number
          nullable: true
    PlatformRevenueChange:
      type: object
      properties:
        amount:
          type: number
        percent:
          type: number
          nullable: true
          description: Null when the comparison period had none.
    PlatformRevenueBreakdown:
      type: object
      properties:
        revenue:
          type: number
        collected:
          type: number
        sales:
          type: integer
        share:
          type: number
          description: Share of the period's revenue, 0-1.
        previousRevenue:
          type: number
          description: In the comparison period; absent without one.
        change:
          $ref: '#/components/schemas/PlatformRevenueChange'
  responses:
    PlatformBadRequest:
      description: Invalid request (bad parameters, or a body that fails validation)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PlatformError'
    PlatformUnauthorized:
      description: Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PlatformError'
    PlatformRateLimited:
      description: Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PlatformError'
  securitySchemes:
    customerApiAuth:
      type: http
      scheme: bearer
      description: >-
        Organization-scoped bearer credential: a customer API key
        (1club_sk_live_...) or an MCP OAuth access token.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.