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

# List forms

> The organization's forms, newest first. A form with `createsAccount: true` is a sign-up form: it registers whoever completes it and can sell plans and products. One with `createsAccount: false` is a fill-in form that only collects answers. `publicUrl` is where each one is filled in, and every form is live there. Questions are not included; read a single form for them.




## OpenAPI

````yaml /openapi-platform.json get /v1/platform/forms
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/forms:
    get:
      tags:
        - Forms
      summary: List forms
      description: >
        The organization's forms, newest first. A form with `createsAccount:
        true` is a sign-up form: it registers whoever completes it and can sell
        plans and products. One with `createsAccount: false` is a fill-in form
        that only collects answers. `publicUrl` is where each one is filled in,
        and every form is live there. Questions are not included; read a single
        form for them.
      parameters:
        - in: query
          name: search
          schema:
            type: string
            maxLength: 120
          description: Match on name or slug, case-insensitive
        - in: query
          name: createsAccount
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
          description: Only sign-up forms (`true`) or only fill-in forms (`false`)
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
        - in: query
          name: offset
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: A page of forms
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformFormPage'
        '401':
          $ref: '#/components/responses/PlatformUnauthorized'
        '403':
          description: API key is missing the required `forms:read` scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformError'
        '429':
          $ref: '#/components/responses/PlatformRateLimited'
      security:
        - customerApiAuth: []
components:
  schemas:
    PlatformFormPage:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/PlatformForm'
        total:
          type: integer
          description: Total forms matching the filters, ignoring pagination
        limit:
          type: integer
        offset:
          type: integer
    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`.
    PlatformForm:
      type: object
      description: 'A form: a page people fill in, live at `publicUrl`.'
      properties:
        id:
          type: integer
        slug:
          type: string
          description: The last part of `publicUrl`. Fixed once the form exists.
        createsAccount:
          type: boolean
          description: >-
            true for a sign-up form (registers the person, can sell); false for
            a fill-in form (collects answers). Fixed once the form exists.
        publicUrl:
          type: string
          nullable: true
          description: >-
            Where the form is filled in, on the organization's own website or
            member portal. It is live: anyone with the link can use it. null
            when the organization has neither switched on, so nothing can open
            the form until one is.
        name:
          type: string
          maxLength: 200
          description: Internal name, shown to staff in the admin portal.
        title:
          type: string
          nullable: true
          maxLength: 200
          description: >-
            Heading at the top of the form. Blank or null falls back to the
            wizard's own wording.
        subtitle:
          type: string
          nullable: true
          maxLength: 200
          description: >-
            Sub-heading under the title. Blank or null falls back to the
            wizard's own wording.
        planStepTitle:
          type: string
          nullable: true
          maxLength: 200
          description: >-
            Heading above the plan picker (sign-up forms). Blank or null falls
            back to the wizard's own wording.
        classTypeStepTitle:
          type: string
          nullable: true
          maxLength: 200
          description: >-
            Heading above the class-type picker (sign-up forms). Blank or null
            falls back to the wizard's own wording.
        planIds:
          type: array
          items:
            type: integer
          maxItems: 100
          description: >-
            Sign-up forms only. Plans the form sells, from GET
            /v1/platform/plans. Each must be active, publicly visible and not a
            season plan (`FORM_PLAN_NOT_SELLABLE` names each refused id and
            why). When any are set, the person must choose one to finish.
        classTypeIds:
          type: array
          items:
            type: integer
          maxItems: 100
          description: >-
            Sign-up forms only. Class types offered as an interest, from GET
            /v1/platform/class-types. Nothing is booked.
        productIds:
          type: array
          items:
            type: integer
          maxItems: 100
          description: >-
            Sign-up forms only. Products the form sells, from GET
            /v1/platform/products. Each must be active, publicly visible and
            sold as a product (`FORM_PRODUCT_NOT_SELLABLE`).
        registrationFor:
          type: string
          enum:
            - individual
            - child
            - both
          description: >-
            Who the form registers: the person filling it in, only their
            children, or both.
        signatureMethod:
          type: string
          enum:
            - draw
            - type
            - check
          description: 'How documents are signed: drawn, typed name, or a checkbox.'
        collectsDocuments:
          type: boolean
          description: >-
            Whether the form asks for the organization's documents and a
            signature. Which documents is set by the organization's document
            rules.
        requiresAuthentication:
          type: boolean
          description: >-
            Fill-in forms only: the person must be signed in to fill it in.
            Refused on a sign-up form (`FORM_AUTHENTICATION_FILL_IN_ONLY`).
        combineSelectionAndDetails:
          type: boolean
          description: >-
            Put the "choose what to buy" step and the details step on one page.
            Needs a form that sells something (`FORM_NOTHING_TO_COMBINE`).
        displayMode:
          type: string
          enum:
            - page
            - dialog
          description: >-
            How a link to the form opens: as its own page, or as a dialog over
            the page it was opened from.
        videoUrl:
          type: string
          nullable: true
          maxLength: 500
          description: >-
            A Cloudinary video URL from the media library, shown as a step
            before review. null removes the video step.
        videoRequired:
          type: boolean
          description: >-
            The person cannot continue until the video has played to the end.
            Needs a video (`FORM_VIDEO_REQUIRED_WITHOUT_VIDEO`).
        videoTitle:
          type: string
          nullable: true
          maxLength: 200
          description: >-
            Heading above the video. Blank or null falls back to the wizard's
            own wording.
        fieldOverrides:
          type: object
          nullable: true
          additionalProperties: false
          description: >-
            Fill-in forms only (`FORM_FIELD_OVERRIDES_FILL_IN_ONLY`; an empty
            object is accepted and ignored on a sign-up form, which asks the
            organization's own sign-up fields instead). Which built-in contact
            fields the form asks: `required` asks it, `hidden` does not. A
            fill-in form cannot ask one optionally. `address` asks the whole
            postal address. On update the map is merged: the fields you send
            change and the rest stay as they are, so send `hidden` to stop
            asking one. null clears every override.
          properties:
            firstName:
              type: string
              enum:
                - required
                - hidden
            lastName:
              type: string
              enum:
                - required
                - hidden
            email:
              type: string
              enum:
                - required
                - hidden
            phone:
              type: string
              enum:
                - required
                - hidden
            dateOfBirth:
              type: string
              enum:
                - required
                - hidden
            gender:
              type: string
              enum:
                - required
                - hidden
            address:
              type: string
              enum:
                - required
                - hidden
        translations:
          type: object
          nullable: true
          additionalProperties:
            type: object
            additionalProperties:
              type: string
          description: >-
            Per-locale wording, as `{ "es": { "title": "..." } }`. Replaces the
            whole map. Translatable fields: title, subtitle, planStepTitle,
            classTypeStepTitle, videoTitle; any other key is refused
            (`INVALID_TRANSLATIONS`).
        packageIds:
          type: array
          items:
            type: integer
          description: 'Read-only here: packages are added in the admin portal.'
        submissionCount:
          type: integer
          description: >-
            How many people have completed it. The answers are not served by
            this API.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        questions:
          type: array
          items:
            $ref: '#/components/schemas/PlatformFormQuestion'
          description: In order. On a single-form read and on every write; not in the list.
    PlatformFormQuestion:
      type: object
      description: >-
        One question on a fill-in form, as read. Resend it with its `id` to keep
        it.
      properties:
        id:
          type: integer
          description: 'Keep this: answers are stored against it.'
        label:
          type: string
        type:
          type: string
          enum:
            - text
            - textarea
            - yes_no
            - select
            - boolean
            - date
            - number
            - email
            - phone
            - url
            - time
        required:
          type: boolean
        placeholder:
          type: string
          nullable: true
        helpText:
          type: string
          nullable: true
        sectionHeading:
          type: string
          nullable: true
          description: Starts a new section above this question.
        options:
          type: array
          items:
            type: string
          description: The choices of a `select` question.
        contactCustomFieldId:
          type: integer
          nullable: true
          description: >-
            A member profile field this question's answer is also saved to,
            linked in the admin portal. Send it back unchanged (or leave it out)
            to keep the link, or null to remove it.
        translations:
          type: object
          nullable: true
          additionalProperties:
            type: object
            additionalProperties:
              type: string
  responses:
    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.