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

# Create add-on service

> Create an add-on service for a scheduling link. People booking the scheduling link can choose it, which adds its `duration` to the booking and its `price` to the amount charged. Images can only be added from the NeetoCal app.


<Info>Replace `{your-subdomain}` with your workspace’s subdomain. <br /> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).</Info>


## OpenAPI

````yaml bundled/add-on-services.yaml POST /meetings/{meeting_sid}/add-on-services
openapi: 3.0.3
info:
  title: NeetoCal Add-on Services APIs
  version: 2.0.0
servers:
  - description: NeetoCal APIs
    url: https://{your-subdomain}.neetocal.com/api/external/v2
    variables:
      your-subdomain:
        default: spinkart
        description: >-
          Replace **spinkart** with your [workspace's
          subdomain](/api/workspace-subdomain).
security: []
tags:
  - name: Add-on Services
    description: >-
      APIs to manage the add-on services people can choose when booking a
      scheduling link.
paths:
  /meetings/{meeting_sid}/add-on-services:
    post:
      tags:
        - Add-on Services
      summary: Create an add-on service
      description: >
        Create an add-on service for a scheduling link. People booking the
        scheduling link can choose it, which adds its `duration` to the booking
        and its `price` to the amount charged. Images can only be added from the
        NeetoCal app.
      parameters:
        - $ref: '#/components/parameters/api_key_header'
        - $ref: '#/components/parameters/meeting_sid'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/add_on_service_create_request'
      responses:
        '201':
          description: Created - Add-on service created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/add_on_service_response'
        '422':
          $ref: '#/components/responses/unprocessable_entity'
components:
  parameters:
    api_key_header:
      in: header
      name: X-Api-Key
      description: >-
        Use the X-Api-Key header to provide your workspace API key. Refer to
        [Authentication](/api/authentication) for more information.
      required: true
      schema:
        type: string
    meeting_sid:
      in: path
      name: meeting_sid
      description: >
        The unique identifier (SID) of the scheduling link you want to use. You
        can get `sid` in different ways. Visit the scheduling link page and then
        click on "Settings" > "Show SID". That will give you `sid`. You can also
        get this from the response of the [List scheduling
        links](/api/scheduling-links/list) endpoint, where it appears as the
        `sid` property for each scheduling link in the response.
      required: true
      schema:
        type: string
        example: vj5pgkh
  schemas:
    add_on_service_create_request:
      type: object
      properties:
        name:
          type: string
          description: Name of the add-on service shown to the person booking.
          example: Sauna
        description:
          $ref: '#/components/schemas/add_on_service_description'
        duration:
          allOf:
            - $ref: '#/components/schemas/add_on_service_duration'
          default: 0
        price:
          $ref: '#/components/schemas/add_on_service_price'
        position:
          type: integer
          description: >
            Position to insert the add-on service at, from 1 to the current
            number of add-on services plus one. The add-on services at and after
            that position move down by one. Defaults to the end of the list.
          example: 1
      required:
        - name
    add_on_service_response:
      type: object
      properties:
        add_on_service:
          $ref: '#/components/schemas/add_on_service'
    add_on_service_description:
      type: string
      description: Description of the add-on service.
      example: 20 minutes in the sauna
    add_on_service_duration:
      type: integer
      minimum: 0
      maximum: 1440
      description: >-
        Minutes the add-on service adds to the booking. Must be `0` for group
        meetings, because everyone in a group meeting shares the same slot.
      example: 30
    add_on_service_price:
      type: number
      nullable: true
      description: >
        Price in the major unit of the scheduling link's currency, for example
        `25.5`. The currency and payment provider are taken from the scheduling
        link's fee, so a positive price needs payments to be enabled on the
        scheduling link. Pass `0` or `null` to make the add-on service free. A
        price above the payment provider's maximum for the currency returns a
        422 error.
      example: 25.5
    add_on_service:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the add-on service.
          example: 77150ec6-d4f0-4665-98f0-34bda69f7b3a
        name:
          type: string
          description: Name of the add-on service shown to the person booking.
          example: Sauna
        description:
          type: string
          nullable: true
          description: Description of the add-on service.
          example: 20 minutes in the sauna
        duration:
          type: integer
          minimum: 0
          maximum: 1440
          description: Minutes the add-on service adds to the booking.
          example: 30
        position:
          type: integer
          description: Display order of the add-on service, starting at 1.
          example: 1
        price:
          type: string
          nullable: true
          description: >-
            Price of the add-on service in the major unit of `currency`,
            returned as a decimal string to keep its exact value (the request
            takes it as a number). `null` when the add-on service is free.
          example: '25.5'
        currency:
          type: string
          nullable: true
          description: >-
            Currency of `price`, taken from the scheduling link's fee. `null`
            when the add-on service is free.
          example: usd
        payment_provider:
          type: string
          nullable: true
          description: >-
            Payment provider used to collect `price`, taken from the scheduling
            link's fee. `null` when the add-on service is free.
          example: stripe
        created_at:
          type: string
          format: date-time
          description: Timestamp when the add-on service was created.
          example: '2026-10-06T18:26:08.033Z'
        updated_at:
          type: string
          format: date-time
          description: Timestamp when the add-on service was last updated.
          example: '2026-10-06T18:26:08.264Z'
  responses:
    unprocessable_entity:
      description: Unprocessable Entity - The request is invalid
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
          examples:
            payment_not_enabled:
              summary: Price on a scheduling link without payments
              value:
                error: >-
                  Payments must be enabled for this scheduling link before you
                  can charge for services.
            invalid_price:
              summary: Price is not zero or a positive number
              value:
                error: >-
                  The price must be zero or a positive number in the meeting's
                  currency
            duration_on_group_meeting:
              summary: Non-zero duration on a group meeting
              value:
                error: >-
                  Duration must be 0 because everyone in a group meeting shares
                  the same fixed duration.
            price_exceeds_maximum:
              summary: Price above the payment provider's maximum
              value:
                error: Price for Sauna must be less than or equal to 999999.99 USD.
            invalid_position:
              summary: Position out of range
              value:
                error: The position must be a whole number between 1 and 2

````

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