> ## 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.

# Create a pricing rule

> Adds a rule to the price list. It applies to new quotes and bookings at once; bookings already made keep the price they were made at.

`adjustmentType` decides what the rule says: `absolute` states the hourly price outright (in `fixedAmountAdjustment`), `fixed` adds that amount per hour (negative for a discount), and `percentage` moves the price by `percentageAdjustment`, -100 to 100. Send only the field your type reads; the other is refused.

`scopes` must be sent: it says which areas, coaches, clubs or class types the rule prices, and an empty list makes it apply to every one of them - so that has to be asked for. `conditions` narrow when it applies; every condition must hold. When several rules match one slot, the lowest `priority` wins. Every id a rule names - in a scope, a `plan` condition or a `with-instructor` condition - must belong to this organization.

A time-of-day condition (`weekdays-time`) is a price band by default: the booking is split at the band's edges and only the part inside it is priced by the rule. Set `match` to `start` or `within` to judge the whole booking instead. Supports the `Idempotency-Key` header.




## OpenAPI

````yaml /openapi-platform.json post /v1/platform/pricing-rules
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.


    Agents and MCP connectors can instead send an OAuth access token (the
    `platformOAuth` scheme), requesting only the scopes the task needs.


    ## 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 |


    ## Versioning and deprecation


    The API is versioned in the path (`/v1`). Changes within a version are
    additive: new endpoints, new optional parameters and new response fields can
    appear at any time, so clients should ignore fields they do not recognise.

    A breaking change ships as a new version.

    An operation due to be removed is first marked `deprecated: true` in this
    spec and announced in the changelog at https://docs.1club.ai/changelog, with
    advance notice before it is withdrawn.
  contact:
    name: 1club API Support
    email: support@1club.ai
servers:
  - url: https://api.1club.ai
    description: Production API
security:
  - customerApiAuth: []
  - platformOAuth: []
tags: []
paths:
  /v1/platform/pricing-rules:
    post:
      tags:
        - Pricing Rules
      summary: Create a pricing rule
      description: >
        Adds a rule to the price list. It applies to new quotes and bookings at
        once; bookings already made keep the price they were made at.


        `adjustmentType` decides what the rule says: `absolute` states the
        hourly price outright (in `fixedAmountAdjustment`), `fixed` adds that
        amount per hour (negative for a discount), and `percentage` moves the
        price by `percentageAdjustment`, -100 to 100. Send only the field your
        type reads; the other is refused.


        `scopes` must be sent: it says which areas, coaches, clubs or class
        types the rule prices, and an empty list makes it apply to every one of
        them - so that has to be asked for. `conditions` narrow when it applies;
        every condition must hold. When several rules match one slot, the lowest
        `priority` wins. Every id a rule names - in a scope, a `plan` condition
        or a `with-instructor` condition - must belong to this organization.


        A time-of-day condition (`weekdays-time`) is a price band by default:
        the booking is split at the band's edges and only the part inside it is
        priced by the rule. Set `match` to `start` or `within` to judge the
        whole booking instead. Supports the `Idempotency-Key` header.
      operationId: createPricingRule
      parameters:
        - in: header
          name: Idempotency-Key
          schema:
            type: string
            maxLength: 255
          description: >-
            Retry-safe key; a repeat of the same request replays the first
            response
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlatformPricingRuleCreate'
      responses:
        '201':
          description: Pricing rule created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformPricingRule'
        '400':
          $ref: '#/components/responses/PlatformBadRequest'
        '401':
          $ref: '#/components/responses/PlatformUnauthorized'
        '403':
          description: API key is missing the required `pricing-rules:write` scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformError'
        '429':
          $ref: '#/components/responses/PlatformRateLimited'
      security:
        - customerApiAuth: []
components:
  schemas:
    PlatformPricingRuleCreate:
      type: object
      description: >-
        Fields accepted when creating a pricing rule. `scopes` must be present:
        an empty list applies the rule to every area, coach and class, so it has
        to be asked for. Send only the amount field your `adjustmentType` reads.
        Unknown fields are rejected.
      required:
        - name
        - adjustmentType
        - scopes
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: >-
            Internal name, shown to staff in the admin portal. Never shown to
            members.
        description:
          type: string
          nullable: true
          maxLength: 2000
          description: Internal note. null clears it.
        isActive:
          type: boolean
          description: >-
            A switched-off rule prices nothing but is kept. Defaults to true on
            create.
        priority:
          type: integer
          description: >-
            Precedence when several rules match one slot: LOWER wins. Give the
            most specific rule the smallest number. Defaults to 0 on create.
        adjustmentType:
          type: string
          enum:
            - percentage
            - fixed
            - absolute
          description: >-
            `absolute` states the hourly price outright; `fixed` adds an amount
            per hour; `percentage` moves the price by a percentage.
        percentageAdjustment:
          type: number
          minimum: -100
          maximum: 100
          description: 'Percentage rules only: -10 is 10% off, 20 is 20% more.'
        fixedAmountAdjustment:
          type: number
          nullable: true
          description: >-
            Fixed rules: the amount added per hour, negative for a discount.
            Absolute rules: the hourly price, zero or more. Scaled by the
            booking length.
        scopes:
          type: array
          maxItems: 20
          items:
            $ref: '#/components/schemas/PlatformPricingRuleScope'
          description: >-
            Which resources the rule prices. Empty means every area, coach and
            class. Replaces the whole list when sent on an update.
        conditions:
          type: array
          maxItems: 20
          items:
            $ref: '#/components/schemas/PlatformPricingRuleCondition'
          description: >-
            When the rule applies; every condition must hold. Empty or omitted
            means always. Replaces the whole list when sent on an update.
    PlatformPricingRule:
      type: object
      description: >-
        One rule of the organization's price list. It applies to the resources
        its `scopes` name (none means every area, coach and class) when every
        one of its `conditions` holds; when several rules match one slot, the
        lowest `priority` wins. Rules are silent: members see the resulting
        price, never the rule's name.
      properties:
        ruleId:
          type: integer
        name:
          type: string
        description:
          type: string
          nullable: true
        isActive:
          type: boolean
        priority:
          type: integer
          description: Lower wins.
        adjustmentType:
          type: string
          enum:
            - percentage
            - fixed
            - absolute
        percentageAdjustment:
          type: number
          nullable: true
          description: Set on percentage rules; null on the others.
        fixedAmountAdjustment:
          type: number
          nullable: true
          description: >-
            The per-hour delta of a fixed rule or the hourly price of an
            absolute one; null on percentage rules.
        scopes:
          type: array
          items:
            $ref: '#/components/schemas/PlatformPricingRuleScope'
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/PlatformPricingRuleCondition'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    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`.
    PlatformPricingRuleScope:
      type: object
      description: >-
        A set of resources the rule prices. `areas`, `instructors`, `clubs` and
        `classTypes` name ids of that kind, all in this organization. A rule
        with several scopes applies to a booking any of them covers.
      required:
        - type
        - ids
      additionalProperties: false
      properties:
        type:
          type: string
          enum:
            - areas
            - instructors
            - clubs
            - classTypes
        ids:
          type: array
          items:
            type: integer
          maxItems: 500
    PlatformPricingRuleCondition:
      description: >-
        One condition a booking must meet for the rule to apply. Weekday names
        are lowercase English; times are 24-hour HH:mm in the club timezone
        (`24:00` ends a window at midnight); dates are YYYY-MM-DD.
      oneOf:
        - type: object
          description: >-
            A time-of-day window, optionally on certain weekdays. By default
            (`match: segment`) it is a price band: the booking is split at its
            edges and only the part inside is priced by the rule. `start`
            applies the rule to the whole booking when it starts inside the
            window; `within` only when it fits entirely inside. Send startTime
            and endTime together, and name weekdays, a window, or both. A window
            cannot run past midnight.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - weekdays-time
            config:
              type: object
              additionalProperties: false
              properties:
                weekdays:
                  type: array
                  items:
                    type: string
                    enum:
                      - monday
                      - tuesday
                      - wednesday
                      - thursday
                      - friday
                      - saturday
                      - sunday
                  maxItems: 7
                  description: >-
                    Days the window applies on. Empty or omitted means every
                    day.
                startTime:
                  type: string
                  pattern: ^([01]\d|2[0-3]):[0-5]\d$
                endTime:
                  type: string
                  pattern: ^(([01]\d|2[0-3]):[0-5]\d|24:00)$
                  description: 'Exclusive: a slot starting at endTime is outside the window.'
                match:
                  type: string
                  enum:
                    - segment
                    - start
                    - within
        - type: object
          description: The booking starts on one of these weekdays.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - days-of-week
            config:
              type: object
              additionalProperties: false
              required:
                - days
              properties:
                days:
                  type: array
                  items:
                    type: string
                    enum:
                      - monday
                      - tuesday
                      - wednesday
                      - thursday
                      - friday
                      - saturday
                      - sunday
                  maxItems: 7
                  minItems: 1
        - type: object
          description: >-
            The whole booking is at least `threshold` hours long, and at most
            `maxThreshold` when sent. Equal values name one exact length.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - duration-threshold
            config:
              type: object
              additionalProperties: false
              required:
                - threshold
              properties:
                threshold:
                  type: number
                  minimum: 0
                maxThreshold:
                  type: number
                  minimum: 0
        - type: object
          description: >-
            A session with a coach and no court is booked for between `min` and
            `max` people (inclusive). The rule then prices the group as a whole.
            A court or class always counts as one.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - group-size
            config:
              type: object
              additionalProperties: false
              required:
                - min
              properties:
                min:
                  type: integer
                  minimum: 1
                max:
                  type: integer
                  minimum: 1
        - type: object
          description: >-
            The booking falls between these dates, inclusive. Send either bound
            or both.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - date-range
            config:
              type: object
              additionalProperties: false
              properties:
                startDate:
                  type: string
                  format: date
                endDate:
                  type: string
                  format: date
        - type: object
          description: >-
            A member rate: the person booking holds one of these membership
            plans. A walk-in with no plan never matches.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - plan
            config:
              type: object
              additionalProperties: false
              required:
                - planIds
              properties:
                planIds:
                  type: array
                  items:
                    type: integer
                  maxItems: 500
                  description: Membership plan ids from GET /v1/platform/plans.
                  minItems: 1
        - type: object
          description: >-
            The court is booked together with a coach - one of these, or any
            coach when the list is empty or omitted. Pair it with an `areas`
            scope.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - with-instructor
            config:
              type: object
              additionalProperties: false
              properties:
                instructorIds:
                  type: array
                  items:
                    type: integer
                  maxItems: 500
                  description: Instructor ids from GET /v1/platform/instructors.
        - type: object
          description: >-
            Who the booking is for: the contact matches this audience - carries
            one of `tags`, is one of `memberTypes`, and so on (every list sent
            must match). Name at least one. Plans are refused here: name a plan
            with the `plan` condition, which also counts a plan bought in the
            same checkout. An anonymous booking never matches, and a quote must
            name `contactId` to be priced by it. For a per-person exception, add
            a second rule on their own tag and give the first rule a higher
            `priority` number - the lower number wins.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - contact-audience
            config:
              type: object
              additionalProperties: false
              minProperties: 1
              properties:
                memberTypes:
                  type: array
                  items:
                    type: string
                  maxItems: 20
                  description: Contact types, e.g. `member`, `lead`.
                tags:
                  type: array
                  items:
                    oneOf:
                      - type: integer
                      - type: string
                        maxLength: 100
                  maxItems: 50
                  description: Tag ids or names the contact carries.
                pipelineStageIds:
                  type: array
                  items:
                    type: integer
                  maxItems: 50
                  description: >-
                    Sales pipeline stages the contact is in (GET
                    /v1/platform/pipeline-stages).
                sourceIds:
                  type: array
                  items:
                    type: integer
                  maxItems: 50
                  description: >-
                    Where the contact came from (GET
                    /v1/platform/contact-sources).
        - type: object
          description: >-
            Demand pricing: how much of the area is still free over the next
            `daysAhead` days, as a percentage, compared with `percent`.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - availability
            config:
              type: object
              additionalProperties: false
              required:
                - daysAhead
                - percent
                - operator
              properties:
                daysAhead:
                  type: integer
                  minimum: 0
                percent:
                  type: number
                  minimum: 0
                  maximum: 100
                operator:
                  type: string
                  enum:
                    - '>'
                    - <
                    - '>='
                    - <=
        - type: object
          description: >-
            How many days ahead the booking is made, compared with `days`. `>`
            14 is an early-bird rate; `<` 2 a last-minute one.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - booking-timing
            config:
              type: object
              additionalProperties: false
              required:
                - days
                - operator
              properties:
                days:
                  type: integer
                  minimum: 0
                operator:
                  type: string
                  enum:
                    - '>'
                    - <
                    - '>='
                    - <=
        - type: object
          description: >-
            The slot is in low demand (more than half the area free) or high
            demand.
          required:
            - type
            - config
          additionalProperties: false
          properties:
            type:
              type: string
              enum:
                - demand-level
            config:
              type: object
              additionalProperties: false
              required:
                - level
              properties:
                level:
                  type: string
                  enum:
                    - low
                    - high
  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.
    platformOAuth:
      type: oauth2
      description: >-
        OAuth 2.1 authorization code flow with PKCE (S256), as used by MCP
        connectors. Register a client dynamically (RFC 7591) at
        https://api.1club.ai/v1/mcp/oauth/register. Each scope grants one
        capability; request only what the integration needs.
      flows:
        authorizationCode:
          authorizationUrl: https://auth.1club.ai/oauth/authorize
          tokenUrl: https://api.1club.ai/v1/mcp/oauth/token
          scopes:
            '*': >-
              Full access - read and manage everything in this organization,
              including capabilities added later
            classes:read: View classes, class types, schedules and progression tracks
            classes:write: >-
              Create, reschedule, and cancel classes, and maintain the class
              types they are run as
            checkins:read: View check-ins
            checkins:write: Check people in, to a booking or on their membership
            content:read: View published content
            content:write: >-
              Create, edit and delete content - posts, FAQs, documents and
              reusable blocks
            website:read: >-
              View your website: pages, sections, layout, styles and publish
              history
            website:write: >-
              Edit your website - pages, sections, navigation and styles. Edits
              stay unpublished until published.
            website:publish: >-
              Publish your website, making unpublished edits visible to the
              public, and roll back to an earlier version
            media:read: View your media library
            media:write: >-
              Add images and videos to your media library and edit their names
              and descriptions
            media:delete: Permanently delete files from your media library
            clubs:read: View club information
            clubs:write: >-
              Edit your clubs' details - name, contact details, address, opening
              hours, amenities and sports. Live on your website, member portal,
              app and 1club.me at once; a club listed on 1club.me sends its
              listing's changes for review.
            transactions:read: View transactions, revenue reports and your chart of accounts
            transactions:write: >-
              Record revenue collected outside 1club, such as a marketplace
              payout for your bookings, and refunds of it. Nothing is charged to
              anyone.
            invoices:read: >-
              View your invoices - who they were issued to, their amounts and
              status - and how much was invoiced over a period
            areas:read: View areas, area types, blocks and availability
            areas:write: >-
              Create and update areas and area types, and block or unblock an
              area
            bookings:read: View bookings
            bookings:write: >-
              Create, change, reschedule and cancel bookings, and add or remove
              participants
            contacts:read: >-
              View contacts, their tags and custom field values, and your sales
              pipeline stages and sources
            contacts:write: >-
              Create and update contacts and tag them, and maintain your tags,
              smart tag rules and contact custom fields
            contacts:delete: >-
              Archive contacts, which cancels their active memberships and all
              their future bookings. Separate from creating and updating because
              those cancellations are not undone by restoring the contact.
            instructors:read: View instructors and their availability
            instructors:write: >-
              Create and update instructors (coaches) and the instructor types
              they are grouped by, including what members pay for a one-to-one
              session and how you pay the coach. Does not grant admin-portal
              access: an instructor created this way has no login and is never
              invited to your staff portal.
            plans:read: View plans and pricing
            plans:write: Create, edit and delete plans and plan categories
            memberships:read: View memberships
            memberships:write: >-
              Sell memberships, set their price and whether they are paid, and
              pause, resume or cancel them
            products:read: >-
              View the product catalogue and its categories, including prices
              and how many are left to sell
            products:write: Create and edit products and product categories
            forms:read: >-
              View your forms and their questions, and how many people have
              completed each. Not the answers themselves.
            forms:write: >-
              Create and edit forms and their questions, including sign-up forms
              that sell your plans and products. Forms are public as soon as
              they are created or changed. Does not delete forms.
            organization:write: >-
              Change organization-wide settings, which take effect immediately.
              That includes which languages you offer, across your website, the
              member portal, the mobile app and email, and what your clubs call
              their booking cards (private training, group activities, areas)
              wherever members book.
            revenue-accounts:write: >-
              Add accounts to your chart of accounts and edit them, including
              which one sales post to by default. Reading the chart needs no
              scope of its own - any of plans, products or transactions admits
              it.
            pricing-rules:read: >-
              View pricing rules - the surcharges, discounts and set prices
              applied when a booking is priced - and quote what a booking would
              cost
            pricing-rules:write: >-
              Create, edit, turn off and delete pricing rules. Changes apply to
              every booking priced afterwards.
            booking-policies:read: >-
              View booking policies: cancellation and refund rules, payment
              timing and booking windows
            booking-policies:write: >-
              Create, edit, duplicate and delete booking policies. Changes apply
              to every booking they cover from then on.
            document-rules:read: >-
              View document rules - which members are asked to sign or accept
              which documents, such as waivers
            document-rules:write: >-
              Create, edit and delete document rules, which decide who must sign
              or accept a document and whether it is required for entry
            templates:read: View your email and SMS templates
            templates:write: Create, edit and delete email and SMS templates
            events:read: View events, their tickets and how many are sold
            events:write: >-
              Create, edit, duplicate and delete events, and publish, unpublish
              or cancel them. Cancelling an event also cancels its attendees'
              bookings.
            messages:read: >-
              View messages sent to and received from your members, and their
              delivery status
            messages:write: >-
              Prepare draft messages to members. Drafts are never sent from
              here: someone at your club reviews and sends them from 1club.
            analytics:read: >-
              View statistics over a period - revenue, bookings, check-ins, how
              full your classes, courts and coaches were, memberships added and
              cancelled, and new members - as totals, never the people or sales
              behind them
            payment-methods:write: >-
              Add, rename and remove the payment methods staff record by hand,
              such as cash or a bank transfer, and choose which ones members may
              pick when paying for a booking. Reading them needs no scope of its
              own - transactions:read admits it.
            staff:read: >-
              View your staff accounts, their roles, and what each role is
              allowed to do
            staff:write: >-
              Change a staff member's role, and what the manager, front desk and
              instructor roles are allowed to do. Only a signed-in person can
              use it, with the same limits as in 1club: an API key is always
              refused.
            notifications:read: >-
              View which notifications each role gets by default, and on which
              channels
            notifications:write: >-
              Change which notifications each role gets and on which channels,
              and apply those defaults to everyone in a role, replacing their
              own choices

````

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