AgendaPro Connect v3 API

Public REST API gateway for AgendaPro. Authenticates external developers with a per-company Bearer API key, enforces scopes and rate limits, and proxies to internal services. 28 operations across 11 resources: available slots, bookings, clients, client custom attributes, custom attribute templates, locations, services, categories, providers, sales, carts and payment requests. Paginated list responses, a flat {error, detail} error envelope, and HMAC-SHA256 signed webhooks for booking, client and payment-request events. Requires an active Pro plan.

Operations 28

GET /v3/available_slots List Available Slots #
GET /v3/bookings List Bookings #
POST /v3/bookings Create Booking #
GET /v3/bookings/{id} Get Booking #
PATCH /v3/bookings/{id} Update Booking #
PATCH /v3/bookings/{id}/cancel Cancel Booking #
GET /v3/clients List Clients #
POST /v3/clients Create Client #
GET /v3/clients/quick-search Quick Search Clients #
GET /v3/clients/{id} Get Client #
PATCH /v3/clients/{id} Update Client #
PATCH /v3/clients/{id}/deactivate Deactivate Client #
GET /v3/clients/{id}/custom_attributes List Client Custom Attributes #
GET /v3/custom_attributes List Custom Attribute Templates #
GET /v3/locations List Locations #
GET /v3/locations/{id} Get Location #
GET /v3/services List Services #
GET /v3/services/{id} Get Service #
GET /v3/categories List Categories #
GET /v3/providers List Providers #
GET /v3/providers/{id} Get Provider #
GET /v3/sales List Sales #
GET /v3/sales/{id} Get Sale #
POST /v3/carts Create Cart #
GET /v3/carts/{id} Get Cart #
PATCH /v3/carts/{id} Update Cart #
POST /v3/carts/{id}/payment_requests Create Payment Request (online checkout) #
PATCH /v3/payment_requests/{id}/cancel Cancel Payment Request #

Documentation

Specifications

Other Resources

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/agendapro-connect-v3-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

agendapro-connect-v3-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Connect v3
  version: 3.0.0
  description: "Public API gateway for AgendaPro.\nAuthenticates external developers, enforces rate limits and scopes, and\
    \ proxies requests to internal services.\n\n## Authentication\n\nAll requests require a Bearer API key in the `Authorization`\
    \ header:\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\nAPI keys are scoped to a single company. The `company_id`\
    \ is derived automatically\nfrom the API key — you never pass it as a parameter.\n\n## Scopes\n\nAPI keys may be restricted\
    \ to specific scopes. Scopes follow the pattern `{resource}:{action}`:\n\n| Scope | Description |\n| --- | --- |\n| `bookings:read`\
    \ | List and show bookings |\n| `bookings:write` | Create, update, and cancel bookings |\n| `clients:read` | List and\
    \ show clients |\n| `clients:write` | Create and update clients |\n| `locations:read` | List and show locations |\n| `services:read`\
    \ | List and show services |\n| `providers:read` | List and show providers |\n| `custom_attributes:read` | List custom\
    \ attribute templates |\n| `sales:read` | List and show sales |\n\nAn API key with empty scopes has full access (all scopes\
    \ granted).\n\n## Rate Limiting\n\nTwo rate limits apply per company:\n\n- **Burst limit**: Maximum requests per minute.\n\
    - **Daily quota**: Maximum requests per day.\n\nRate limit status is returned in response headers:\n\n| Header | Description\
    \ |\n| --- | --- |\n| `X-RateLimit-Limit` | Daily quota limit |\n| `X-RateLimit-Remaining` | Daily requests remaining\
    \ |\n| `X-RateLimit-Reset` | Unix timestamp when daily quota resets |\n| `X-RateLimit-Burst-Limit` | Burst (per-minute)\
    \ limit |\n| `X-RateLimit-Burst-Remaining` | Burst requests remaining |\n| `X-RateLimit-Burst-Reset` | Unix timestamp\
    \ when burst window resets |\n\nWhen either limit is exceeded, the API returns `429 Too Many Requests` with a `Retry-After`\
    \ header.\n\n## Pagination\n\nList endpoints return paginated responses wrapped in a `data` array with a `pagination`\
    \ metadata object:\n\n```json\n{\n  \"data\": [...],\n  \"pagination\": {\n    \"current_page\": 1,\n    \"per_page\"\
    : 30,\n    \"next_page\": null,\n    \"prev_page\": null,\n    \"total_records\": 95,\n    \"total_pages\": 4\n  }\n}\n\
    ```\n\n## Errors\n\nAll error responses use a consistent `{error, detail}` format:\n\n```json\n{\n  \"error\": \"error_type\"\
    ,\n  \"detail\": \"additional_context\"\n}\n```\n"
servers:
- url: https://connect.agendapro.com
  description: Production
tags:
- name: Available Slots
  description: Query available booking slots for a service at a location
- name: Bookings
  description: Booking management (list, show, create, update, cancel)
- name: Clients
  description: Client management (list, show, create, update) and custom attributes
- name: Custom Attributes
  description: Custom attribute templates (company-level definitions)
- name: Locations
  description: Location listing and details
- name: Services
  description: Service catalog listing and details
- name: Providers
  description: Service provider listing and details
- name: Sales
  description: Sales records (read-only)
- name: Carts
  description: Shopping carts for the online payment flow
- name: Payment Requests
  description: Online payment requests (checkout URL) on a cart
security:
- BearerAuth: []
paths:
  /v3/available_slots:
    get:
      operationId: listAvailableSlots
      summary: List Available Slots
      description: 'Returns available booking slots for a service at a location on a given date.


        Results are grouped into a `slots` array and a `metadata` object.

        The `slots` array contains individual time windows; `metadata` summarises the query.


        ### Important Notes


        - Results are scoped to the company associated with the API key.

        - `location_id` and `start_date` are required.

        - Requires `bookings:read` scope.


        ### Errors Dictionary


        | **Status** | **Error** | **Detail** | **Description** |

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

        | 401 | unauthorized | invalid_api_key | Missing or invalid Bearer token. |

        | 401 | unauthorized | api_config_inactive | API access is inactive for this company. |

        | 403 | forbidden | scope_denied | API key lacks `bookings:read` scope. |

        | 404 | location_not_found |  | Location not found or does not belong to the company. |

        | 429 | rate_limited | burst_limit_exceeded | Per-minute request limit exceeded. |

        | 429 | rate_limited | daily_quota_exceeded | Daily request quota exceeded. |

        | 502 | upstream_unavailable |  | The upstream service is unavailable. |

        '
      tags:
      - Available Slots
      parameters:
      - name: location_id
        in: query
        description: Location ID to query slots for.
        required: true
        schema:
          type: integer
      - name: start_date
        in: query
        description: Date to query slots for (YYYY-MM-DD).
        required: true
        schema:
          type: string
          format: date
          example: '2026-04-08'
      - name: service_id
        in: query
        description: Filter by service ID.
        required: false
        schema:
          type: integer
      - name: provider_id
        in: query
        description: Filter by provider ID.
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Available slots returned.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      slots:
                        type: array
                        items:
                          $ref: '#/components/schemas/AvailableSlot'
                      metadata:
                        $ref: '#/components/schemas/AvailableSlotsMetadata'
              example:
                data:
                  slots:
                  - start_time: 09:00
                    end_time: 09:30
                    provider_id: 12964
                    provider_name: Dobby
                  - start_time: 09:30
                    end_time: '10:00'
                    provider_id: 12964
                    provider_name: Dobby
                  metadata:
                    location_id: 3257
                    date: '2026-04-08'
                    service_id: 3698
                    duration: 30
                    slots_count: 22
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/UpstreamUnavailable'
  /v3/bookings:
    get:
      operationId: listBookings
      summary: List Bookings
      description: 'This endpoint returns a paginated list of bookings for the company.


        ### Important Notes


        - Results are scoped to the company associated with the API key.

        - At least one entity filter is required: `client_id`, `location_id`, `service_id`, or `service_provider_id`. The
        `start_date`/`end_date` parameters narrow results further but do not satisfy this requirement on their own.

        - Requires `bookings:read` scope.

        - `sale` may be the sale of a membership plan, which covers several bookings. Do not aggregate amounts by `sale.id`.


        ### Errors Dictionary


        | **Status** | **Error** | **Detail** | **Description** |

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

        | 400 | required | params | No entity filter provided. Supply at least one of `client_id`, `location_id`, `service_id`,
        or `service_provider_id`. |

        | 401 | unauthorized | invalid_api_key | Missing or invalid Bearer token. |

        | 401 | unauthorized | api_config_inactive | API access is inactive for this company. |

        | 403 | forbidden | scope_denied | API key lacks `bookings:read` scope. |

        | 429 | rate_limited | burst_limit_exceeded | Per-minute request limit exceeded. |

        | 429 | rate_limited | daily_quota_exceeded | Daily request quota exceeded. |

        | 502 | upstream_unavailable |  | The upstream service is unavailable. |

        '
      tags:
      - Bookings
      parameters:
      - name: client_id
        in: query
        description: Filter by client ID.
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        description: Filter by location ID.
        required: false
        schema:
          type: integer
      - name: service_id
        in: query
        description: Filter by service ID.
        required: false
        schema:
          type: integer
      - name: service_provider_id
        in: query
        description: Filter by service provider ID.
        required: false
        schema:
          type: integer
      - name: scheduled
        in: query
        description: Filter by scheduled status.
        required: false
        schema:
          type: boolean
      - name: status_id
        in: query
        description: Filter by status ID.
        required: false
        schema:
          type: integer
      - name: start_date
        in: query
        description: Filter bookings from this date (YYYY-MM-DD).
        required: false
        schema:
          type: string
          format: date
      - name: end_date
        in: query
        description: Filter bookings until this date (YYYY-MM-DD).
        required: false
        schema:
          type: string
          format: date
      - name: page
        in: query
        description: Page number (defaults to 1).
        required: false
        schema:
          type: integer
          minimum: 1
          default: 1
      - name: per_page
        in: query
        description: Records per page (defaults to 30, max 100).
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 30
      responses:
        '200':
          description: Paginated list of bookings.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingListResponse'
              examples:
                bookingList:
                  summary: '[Success] 200 OK - Booking list'
                  value:
                    data:
                    - id: 12345
                      start_time: '2026-03-10T10:00:00-03:00'
                      end_time: '2026-03-10T10:30:00-03:00'
                      status_id: 1
                      status:
                        id: 1
                        name: Confirmed
                        internal_name: confirmed
                        description: null
                      service_id: 10
                      service:
                        id: 10
                        name: Haircut
                      service_provider_id: 5
                      service_provider:
                        id: 5
                        public_name: John Stylist
                      client_id: 42
                      location_id: 1
                      location:
                        id: 1
                        name: Sucursal Providencia
                      price: '15000.0'
                      list_price: '15000.0'
                      discount: null
                      notes: null
                      scheduled: true
                      time_resource_id: null
                      company_id: 100
                      sale:
                        id: 8842
                        status: paid
                        cart_id: 9310
                      created_at: '2026-03-09T14:00:00-03:00'
                      updated_at: '2026-03-09T14:00:00-03:00'
                    pagination:
                      current_page: 1
                      per_page: 30
                      next_page: null
                      prev_page: null
                      total_records: 1
                      total_pages: 1
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/UpstreamUnavailable'
    post:
      operationId: createBooking
      summary: Create Booking
      description: 'This endpoint creates a new booking.


        ### Important Notes


        - Requires `bookings:write` scope.

        - Notifications (email, SMS, WhatsApp) are disabled for bookings created via the public API.

        - The `creative_source` is automatically set to `connect`.


        ### Errors Dictionary


        | **Status** | **Error** | **Detail** | **Description** |

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

        | 401 | unauthorized | invalid_api_key | Missing or invalid Bearer token. |

        | 401 | unauthorized | api_config_inactive | API access is inactive for this company. |

        | 403 | forbidden | scope_denied | API key lacks `bookings:write` scope. |

        | 429 | rate_limited | burst_limit_exceeded | Per-minute request limit exceeded. |

        | 429 | rate_limited | daily_quota_exceeded | Daily request quota exceeded. |

        | 502 | upstream_unavailable |  | The upstream service is unavailable. |

        '
      tags:
      - Bookings
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBookingRequest'
            examples:
              createBooking:
                summary: '[Request] Create a booking'
                value:
                  start_time: '2026-03-10T10:00:00-03:00'
                  end_time: '2026-03-10T10:30:00-03:00'
                  service_id: 10
                  provider_id: 5
                  client_id: 42
                  location_id: 1
                  status_id: 1
      responses:
        '201':
          description: Booking created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Booking'
              examples:
                bookingCreated:
                  summary: '[Success] 201 Created - Booking created'
                  value:
                    id: 12345
                    start_time: '2026-03-10T10:00:00-03:00'
                    end_time: '2026-03-10T10:30:00-03:00'
                    status_id: 1
                    status:
                      id: 1
                      name: Confirmed
                      internal_name: confirmed
                      description: null
                    service_id: 10
                    service:
                      id: 10
                      name: Haircut
                    service_provider_id: 5
                    service_provider:
                      id: 5
                      public_name: John Stylist
                    client_id: 42
                    location_id: 1
                    location:
                      id: 1
                      name: Sucursal Providencia
                    price: '15000.0'
                    list_price: '15000.0'
                    discount: null
                    notes: null
                    scheduled: true
                    time_resource_id: null
                    company_id: 100
                    sale: null
                    created_at: '2026-03-09T14:00:00-03:00'
                    updated_at: '2026-03-09T14:00:00-03:00'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/UpstreamUnavailable'
  /v3/bookings/{id}:
    get:
      operationId: getBooking
      summary: Get Booking
      description: 'This endpoint returns a single booking by ID.


        ### Errors Dictionary


        | **Status** | **Error** | **Detail** | **Description** |

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

        | 401 | unauthorized | invalid_api_key | Missing or invalid Bearer token. |

        | 401 | unauthorized | api_config_inactive | API access is inactive for this company. |

        | 403 | forbidden | scope_denied | API key lacks `bookings:read` scope. |

        | 404 | not_found | booking | Booking not found. |

        | 429 | rate_limited | burst_limit_exceeded | Per-minute request limit exceeded. |

        | 429 | rate_limited | daily_quota_exceeded | Daily request quota exceeded. |

        | 502 | upstream_unavailable |  | The upstream service is unavailable. |

        '
      tags:
      - Bookings
      parameters:
      - $ref: '#/components/parameters/BookingId'
      responses:
        '200':
          description: Booking found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Booking'
              examples:
                bookingFound:
                  summary: '[Success] 200 OK - Booking found'
                  value:
                    id: 12345
                    start_time: '2026-03-10T10:00:00-03:00'
                    end_time: '2026-03-10T10:30:00-03:00'
                    status_id: 1
                    status:
                      id: 1
                      name: Confirmed
                      internal_name: confirmed
                      description: null
                    service_id: 10
                    service:
                      id: 10
                      name: Haircut
                    service_provider_id: 5
                    service_provider:
                      id: 5
                      public_name: John Stylist
                    client_id: 42
                    location_id: 1
                    location:
                      id: 1
                      name: Sucursal Providencia
                    price: '15000.0'
                    list_price: '15000.0'
                    discount: null
                    notes: null
                    scheduled: true
                    time_resource_id: null
                    company_id: 100
                    sale:
                      id: 8842
                      status: paid
                      cart_id: 9310
                    created_at: '2026-03-09T14:00:00-03:00'
                    updated_at: '2026-03-09T14:00:00-03:00'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/UpstreamUnavailable'
    patch:
      operationId: updateBooking
      summary: Update Booking
      description: 'This endpoint updates an existing booking. Only provided fields are updated (partial update).


        ### Customer policy enforcement


        Updates are validated against the merchant''s customer policy before being applied. If the merchant has disabled edits,
        the booking is too close to its start time, or it has reached its maximum number of changes, the request is rejected
        with `422 restricted` and the `detail` field identifies which rule tripped:


        | **Detail** | **Meaning** |

        | --- | --- |

        | `can_edit` | Merchant disabled edits via the customer flow. |

        | `before_edit_booking` | Booking is within the merchant''s pre-start lock window (no edits allowed this close to
        `start_time`). |

        | `max_changes` | Booking already reached the merchant''s maximum number of changes. |


        These values are configured by the merchant in **[Configuraciones > Sitio web > Edición y cancelación de reservas
        en línea](https://app.agendapro.com/company_settings/bookings)**.


        Clients integrating against this API should surface these conditions to their end users as "the merchant does not
        allow this change" rather than retrying the request.


        ### Errors Dictionary


        | **Status** | **Error** | **Detail** | **Description** |

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

        | 401 | unauthorized | invalid_api_key | Missing or invalid Bearer token. |

        | 401 | unauthorized | api_config_inactive | API access is inactive for this company. |

        | 403 | forbidden | scope_denied | API key lacks `bookings:write` scope. |

        | 404 | not_found | booking | Booking not found. |

        | 422 | restricted | can_edit | Merchant has disabled edits via the customer flow. |

        | 422 | restricted | before_edit_booking | Booking is within the merchant''s pre-start lock window. |

        | 422 | restricted | max_changes | Booking has reached the merchant''s maximum number of changes. |

        | 429 | rate_limited | burst_limit_exceeded | Per-minute request limit exceeded. |

        | 429 | rate_limited | daily_quota_exceeded | Daily request quota exceeded. |

        | 502 | upstream_unavailable |  | The upstream service is unavailable. |

        '
      tags:
      - Bookings
      parameters:
      - $ref: '#/components/parameters/BookingId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateBookingRequest'
            examples:
              rescheduleBooking:
                summary: '[Request] Reschedule a booking'
                value:
                  start_time: '2026-03-11T14:00:00-03:00'
                  end_time: '2026-03-11T14:30:00-03:00'
      responses:
        '200':
          description: Booking updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Booking'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          description: Update rejected by the merchant's customer policy.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorDetailResponse'
              examples:
                canEdit:
                  summary: '[Error] 422 - Merchant disabled edits'
                  value:
                    error: restricted
                    detail: can_edit
                beforeEditBooking:
                  summary: '[Error] 422 - Inside pre-start lock window'
                  value:
                    error: restricted
                    detail: before_edit_booking
                maxChanges:
                  summary: '[Error] 422 - Maximum changes reached'
                  value:
                    error: restricted
                    detail: max_changes
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/UpstreamUnavailable'
  /v3/bookings/{id}/cancel:
    patch:
      operationId: cancelBooking
      summary: Cancel Booking
      description: 'This endpoint cancels a booking.


        ### Customer policy enforcement


        Cancellations are validated against the merchant''s customer policy before being applied. If the merchant has disabled
        cancellations, the booking is too close to its start time, or it has reached its maximum number of changes, the request
        is rejected with `422 restricted` and the `detail` field identifies which rule tripped:


        | **Detail** | **Meaning** |

        | --- | --- |

        | `can_cancel` | Merchant disabled cancellations via the customer flow. |

        | `before_edit_booking` | Booking is within the merchant''s pre-start lock window (no cancellations allowed this close
        to `start_time`). |

        | `max_changes` | Booking already reached the merchant''s maximum number of changes. |


        These values are configured by the merchant in **[Configuraciones > Sitio web > Edición y cancelación de reservas
        en línea](https://app.agendapro.com/company_settings/bookings)**.


        Clients integrating against this API should surface these conditions to their end users as "the merchant does not
        allow this cancellation" rather than retrying the request.


        ### Errors Dictionary


        | **Status** | **Error** | **Detail** | **Description** |

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

        | 401 | unauthorized | invalid_api_key | Missing or invalid Bearer token. |

        | 401 | unauthorized | api_config_inactive | API access is inactive for this company. |

        | 403 | forbidden | scope_denied | API key lacks `bookings:write` scope. |

        | 404 | not_found | booking | Booking not found. |

        | 422 | restricted | can_cancel | Merchant has disabled cancellations via the customer flow. |

        | 422 | restricted | before_edit_booking | Booking is within the merchant''s pre-start lock window. |

        | 422 | restricted | max_changes | Booking has reached the merchant''s maximum number of changes. |

        | 429 | rate_limited | burst_limit_exceeded | Per-minute request limit exceeded. |

        | 429 | rate_limited | daily_quota_exceeded | Daily request quota exceeded. |

        | 502 | upstream_unavailable |  | The upstream service is unavailable. |

        '
      tags:
      - Bookings
      parameters:
      - $ref: '#/components/parameters/BookingId'
      responses:
        '204':
          description: Booking cancelled.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          description: Cancellation rejected by the merchant's customer policy.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorDetailResponse'
              examples:
                canCancel:
                  summary: '[Error] 422 - Merchant disabled cancellations'
                  value:
                    error: restricted
                    detail: can_cancel
                beforeEditBooking:
                  summary: '[Error] 422 - Inside pre-start lock window'
                  value:
                    error: restricted
                    detail: before_edit_booking
                maxChanges:
                  summary: '[Error] 422 - Maximum changes reached'
                  value:
                    error: restricted
                    detail: max_changes
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/UpstreamUnavailable'
  /v3/clients:
    get:
      operationId: listClients
      summary: List Clients
      description: 'This endpoint returns a paginated list of clients for the company.


        ### Errors Dictionary


        | **Status** | **Error** | **Detail** | **Description** |

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

        | 401 | unauthorized | invalid_api_key | Missing or invalid Bearer token. |

        | 401 | unauthorized | api_config_inactive | API access is inactive for this company. |

        | 403 | forbidden | scope_denied | API key lacks `clients:read` scope. |

        | 429 | rate_limited | burst_limit_exceeded | Per-minute request limit exceeded. |

        | 429 | rate_limited | daily_quota_exceeded | Daily request quota exceeded. |

        | 502 | upstream_unavailable |  | The upstream service is unavailable. |

        '
      tags:
      - Clients
      parameters:
      - name: page
        in: query
        description: Page number (defaults to 1).
        required: false
        schema:
          type: integer
          minimum: 1
          default: 1
      - name: per_page
        in: query
        description: Records per page (defaults to 30, max 100).
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 30
      responses:
        '200':
          description: Paginated list of clients.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientListResponse'
              examples:
                clientList:
                  summary: '[Success] 200 OK - Client list'
                  value:
                    data:
                    - id: 223190
                      first_name: Maria
                      last_name: Lopez
                      email: maria.lopez@example.com
                      phone: '+56912345678'
                      second_phone: null
                      identification_number: 12345678-9
                      address: Av. Providencia 1234
                      district: Providencia
                      city: Santiago
                      region: RM
                      age: 30
                      gender: 1
                      birth_day: 15
                      birth_month: 6
                      birth_year: 1995
                      record_number: C-0001
                      photo: null
                      nationality: null
                      phone_country: CL
                      active: true
                      custom_attributes: []
                      created_at: '2025-01-01T12:00:00-03:00'
                      updated_at: '2025-06-15T09:30:00-03:00'
                    pagination:
                      current_page: 1
                      per_page: 30
                      next_page: null
                      prev_page: null
                      total_records: 1
                      total_pages: 1
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/UpstreamUnavailable'
    post:
      operationId: createClient
      summary: Create Client
      description: 'This endpoint creates a new client for the company.


        ### Important Notes


        - At least one of `last_name`, `email`, or `phone` is required by business logic.

        - Email is normalized to lowercase.

        - Phone must follow E.164 format.


        ### Errors Dictionary


        | **Status** | **Error** | **Detail** | **Description** |

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

        | 401 | unauthorized | invalid_api_key | Missing or invalid Bearer token. |

        | 401 | unauthorized | api_config_inactive | API access is inactive for this company. |

        | 403 | forbidden | scope_denied | API key lacks `clients:write` scope. |

        | 429 | rate_limited | burst_limit_exceeded | Per-minute request limit exceeded. |

        | 429 | rate_limited | daily_quota_exceeded | Daily request quota exceeded. |

        | 502 | upstream_unavailable |  | The upstream service is unavailable. |

        '
      tags:
      - Clients
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateClientRequest'
            examples:
              createClient:
                summary: '[Request] Create a client'
                value:
                  first_name: Maria
                  last_name: Lopez
                  email: maria.lopez@example.com
                  phone: '+56912345678'
      responses:
        '201':
          description: Client created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Client'
        '401':
          $ref: '#/compon

# --- truncated at 32 KB (140 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/agendapro/refs/heads/main/openapi/agendapro-connect-v3-openapi.yml