openapi: 3.0.3
info:
  title: Integrate.io (Xplenty) ETL API
  description: |
    The Integrate.io ETL API (formerly Xplenty) provides functions for controlling and monitoring
    clusters, jobs, packages, schedules, deliveries, connections, and account management.

    After defining a data processing package using the Integrate.io web application, you can call
    this API to create clusters, run jobs, monitor their progress, and terminate jobs and clusters.

    ## Authentication
    All API calls require your API key via HTTP Basic Authentication.
    Enter your API key as the **username** and leave the **password** blank.
    ```
    curl -u YOUR_API_KEY: https://api.xplenty.com/{account_id}/api/clusters
    ```

    ## API Versioning
    All requests must include the `Accept` header with the API version:
    ```
    Accept: application/vnd.xplenty+json; version=2
    ```
    Without this header, requests may be routed incorrectly and return `404` errors.

    ## Pagination
    Collection endpoints support `offset` and `limit` query parameters.
    Pagination info is provided via the `Link` header (RFC 5988).

    ## Rate Limits
    Each user is allocated 5,000 credits per hour. Most API calls cost 1 credit.
    Exceeding the limit returns a `429 Too Many Requests` response.
  version: "2.0"
  contact:
    name: Integrate.io Support
    url: https://www.integrate.io
  license:
    name: Proprietary

servers:
  - url: https://api.xplenty.com/{account_id}/api
    description: Production API
    variables:
      account_id:
        description: Your Integrate.io (Xplenty) account ID
        default: my-account

security:
  - apiKeyAuth: []

tags:
  - name: Clusters
    description: Create, manage, monitor, and terminate compute clusters
  - name: Jobs
    description: Run, monitor, and manage data processing jobs
  - name: Packages
    description: Manage data flow packages
  - name: Package Validations
    description: Validate package configurations
  - name: Schedules
    description: Create and manage recurring job schedules
  - name: Deliveries
    description: Manage data delivery blueprints
  - name: Connections
    description: Manage data source and destination connections
  - name: Connection Groups
    description: Organize database and cloud storage connections into named groups
  - name: Accounts
    description: Manage Integrate.io accounts
  - name: Members
    description: Manage account members and roles
  - name: Users
    description: Manage authenticated user information
  - name: Public Keys
    description: Manage SSH public keys
  - name: Notifications
    description: View and manage user notifications
  - name: Hooks
    description: Manage webhooks for event notifications
  - name: System
    description: System information (regions, stacks, time zones, variables)
  - name: Billing
    description: Subscription, invoices, and payment methods

paths:
  # ==================== CLUSTERS ====================
  /clusters:
    get:
      tags: [Clusters]
      summary: List Clusters
      description: Returns a list of clusters associated with the authenticated account.
      operationId: listClusters
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
        - name: status
          in: query
          description: Filter by cluster status
          schema:
            type: string
            enum: [pending, creating, available, scaling, pending_terminate, terminating, terminated, error]
        - name: sort
          in: query
          description: Sort field
          schema:
            type: string
            enum: [id, name, nodes, type, status, created_at, updated_at]
        - name: direction
          in: query
          description: Sort direction
          schema:
            type: string
            enum: [asc, desc]
            default: desc
        - name: since
          in: query
          description: Only return clusters updated at the given time or later (ISO 8601)
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Cluster'
          headers:
            Link:
              $ref: '#/components/headers/LinkPagination'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      tags: [Clusters]
      summary: Create Cluster
      description: |
        Creates a new cluster. A cluster is a group of machines (nodes) allocated exclusively
        to your account. You will need an active cluster to run jobs.
      operationId: createCluster
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClusterCreate'
            example:
              name: "my cluster"
              description: "production cluster"
              type: "production"
              nodes: 2
              region: "amazon-web-services::us-east-1"
              terminate_on_idle: true
              time_to_idle: 3600
      responses:
        '201':
          description: Cluster created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Cluster'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'

  /clusters/{cluster_id}:
    parameters:
      - $ref: '#/components/parameters/clusterIdParam'

    get:
      tags: [Clusters]
      summary: Get Cluster Information
      description: Returns details for the specified cluster, including its status.
      operationId: getCluster
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Cluster'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'

    put:
      tags: [Clusters]
      summary: Update Cluster
      description: Updates the specified cluster's settings, such as name, description, or node count.
      operationId: updateCluster
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClusterUpdate'
      responses:
        '200':
          description: Cluster updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Cluster'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'

    delete:
      tags: [Clusters]
      summary: Terminate Cluster
      description: |
        Terminates the specified cluster, releasing its resources.
        Use this when all jobs on the cluster are completed.
      operationId: terminateCluster
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Cluster termination initiated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Cluster'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'

  /clusters/search:
    get:
      tags: [Clusters]
      summary: Search Clusters
      description: Search clusters by name or description.
      operationId: searchClusters
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: q
          in: query
          required: true
          description: Search query string
          schema:
            type: string
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Cluster'

  # ==================== JOBS ====================
  /jobs:
    get:
      tags: [Jobs]
      summary: List Jobs
      description: Returns a list of jobs associated with the authenticated account.
      operationId: listJobs
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
        - name: status
          in: query
          description: Filter by job status
          schema:
            type: string
            enum: [idle, pending, queued, running, completed, failed, pending_stoppage, stopping, stopped]
        - name: sort
          in: query
          description: Sort field
          schema:
            type: string
            enum: [id, status, created_at, updated_at]
        - name: direction
          in: query
          description: Sort direction
          schema:
            type: string
            enum: [asc, desc]
            default: desc
        - name: since
          in: query
          description: Only return jobs updated at the given time or later (ISO 8601)
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Job'
          headers:
            Link:
              $ref: '#/components/headers/LinkPagination'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      tags: [Jobs]
      summary: Run Job
      description: |
        Creates and runs a new job. You must specify the cluster to run on and the package
        whose workflow the job should perform. You can also pass static and dynamic variables.
      operationId: runJob
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobCreate'
            example:
              cluster_id: 167
              package_id: 103
              variables:
                MY_STATIC_VAR: "some static variable"
              dynamic_variables:
                current_time: "CurrentTime()"
                MY_CURRENT_TIME: "$CURRENT_TIME_VAR"
      responses:
        '201':
          description: Job created and started
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Job'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'

  /jobs/{job_id}:
    parameters:
      - $ref: '#/components/parameters/jobIdParam'

    get:
      tags: [Jobs]
      summary: Get Job Information
      description: Returns details for the specified job, including status, progress, and outputs.
      operationId: getJob
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Job'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'

    delete:
      tags: [Jobs]
      summary: Terminate Job
      description: Terminates the specified job, stopping its execution and releasing resources.
      operationId: terminateJob
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Job termination initiated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Job'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'

  /jobs/{job_id}/children:
    get:
      tags: [Jobs]
      summary: List Job Children
      description: Returns child jobs of the specified job.
      operationId: listJobChildren
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/jobIdParam'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Job'

  /jobs/{job_id}/variables:
    get:
      tags: [Jobs]
      summary: Get Job Execution Variables
      description: Returns the execution variables for the specified job.
      operationId: getJobVariables
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/jobIdParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: object
                additionalProperties: true

  /jobs/{job_id}/outputs/{output_id}/preview:
    get:
      tags: [Jobs]
      summary: Preview Job Output
      description: Returns a preview of the specified job output.
      operationId: previewJobOutput
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/jobIdParam'
        - name: output_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: object

  /jobs/search:
    get:
      tags: [Jobs]
      summary: Search Jobs
      description: Search jobs by various criteria.
      operationId: searchJobs
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: q
          in: query
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Job'

  # ==================== PACKAGES ====================
  /packages:
    get:
      tags: [Packages]
      summary: List Packages
      description: Returns the list of packages in the account.
      operationId: listPackages
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
        - name: sort
          in: query
          schema:
            type: string
            enum: [id, name, created_at, updated_at]
        - name: direction
          in: query
          schema:
            type: string
            enum: [asc, desc]
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Package'

    post:
      tags: [Packages]
      summary: Create Package
      description: Creates a new data flow package.
      operationId: createPackage
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PackageCreate'
      responses:
        '201':
          description: Package created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Package'

  /packages/{package_id}:
    parameters:
      - $ref: '#/components/parameters/packageIdParam'

    get:
      tags: [Packages]
      summary: Get Package Information
      description: Returns details for the specified package.
      operationId: getPackage
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Package'
        '404':
          $ref: '#/components/responses/NotFound'

    put:
      tags: [Packages]
      summary: Update Package
      description: Updates the specified package.
      operationId: updatePackage
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PackageUpdate'
      responses:
        '200':
          description: Package updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Package'

    delete:
      tags: [Packages]
      summary: Delete Package
      description: Deletes the specified package.
      operationId: deletePackage
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Package deleted
        '404':
          $ref: '#/components/responses/NotFound'

  /packages/{package_id}/export:
    get:
      tags: [Packages]
      summary: Export Package as JSON
      description: Exports the specified package definition as JSON.
      operationId: exportPackage
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/packageIdParam'
      responses:
        '200':
          description: Package JSON export
          content:
            application/json:
              schema:
                type: object

  /packages/search:
    get:
      tags: [Packages]
      summary: Search Packages
      description: Search packages by name or description.
      operationId: searchPackages
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: q
          in: query
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Package'

  # ==================== PACKAGE VALIDATIONS ====================
  /packages/{package_id}/validations:
    get:
      tags: [Package Validations]
      summary: List Package Validations
      description: Returns a list of validations for the specified package.
      operationId: listPackageValidations
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/packageIdParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PackageValidation'

    post:
      tags: [Package Validations]
      summary: Run Package Validation
      description: Initiates an asynchronous validation of the specified package.
      operationId: runPackageValidation
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/packageIdParam'
      responses:
        '201':
          description: Validation initiated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/PackageValidation'

  /packages/{package_id}/validations/sync:
    post:
      tags: [Package Validations]
      summary: Run Package Validation (Synchronous)
      description: Runs a synchronous validation of the specified package and waits for the result.
      operationId: runPackageValidationSync
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/packageIdParam'
      responses:
        '200':
          description: Validation result
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/PackageValidation'

  /packages/{package_id}/validations/{validation_id}:
    get:
      tags: [Package Validations]
      summary: Get Package Validation Information
      description: Returns the status and result of a specific package validation.
      operationId: getPackageValidation
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/packageIdParam'
        - name: validation_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/PackageValidation'

  # ==================== SCHEDULES ====================
  /schedules:
    get:
      tags: [Schedules]
      summary: List Schedules
      description: Returns all schedules in the account.
      operationId: listSchedules
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
        - name: status
          in: query
          schema:
            type: string
            enum: [enabled, disabled]
        - name: sort
          in: query
          schema:
            type: string
            enum: [id, name, created_at, updated_at]
        - name: direction
          in: query
          schema:
            type: string
            enum: [asc, desc]
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Schedule'

    post:
      tags: [Schedules]
      summary: Create Schedule
      description: Creates a new schedule to run packages periodically.
      operationId: createSchedule
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ScheduleCreate'
      responses:
        '201':
          description: Schedule created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Schedule'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'

  /schedules/{schedule_id}:
    parameters:
      - $ref: '#/components/parameters/scheduleIdParam'

    get:
      tags: [Schedules]
      summary: Get Schedule Information
      description: Returns details for the specified schedule.
      operationId: getSchedule
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Schedule'
        '404':
          $ref: '#/components/responses/NotFound'

    put:
      tags: [Schedules]
      summary: Update Schedule
      description: Updates the specified schedule.
      operationId: updateSchedule
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ScheduleUpdate'
      responses:
        '200':
          description: Schedule updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Schedule'

    delete:
      tags: [Schedules]
      summary: Delete Schedule
      description: Deletes the specified schedule.
      operationId: deleteSchedule
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Schedule deleted
        '404':
          $ref: '#/components/responses/NotFound'

  /schedules/{schedule_id}/run:
    post:
      tags: [Schedules]
      summary: Run Schedule
      description: Manually triggers the specified schedule to run immediately.
      operationId: runSchedule
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/scheduleIdParam'
      responses:
        '200':
          description: Schedule triggered
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Schedule'

  /schedules/search:
    get:
      tags: [Schedules]
      summary: Search Schedules
      description: Searches the account's schedules by name or description.
      operationId: searchSchedules
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: q
          in: query
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Schedule'

  # ==================== DELIVERIES ====================
  /deliveries:
    get:
      tags: [Deliveries]
      summary: List Deliveries
      description: Returns all deliveries in the account.
      operationId: listDeliveries
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Delivery'

    post:
      tags: [Deliveries]
      summary: Create Delivery
      description: Creates a new data delivery blueprint.
      operationId: createDelivery
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeliveryCreate'
      responses:
        '201':
          description: Delivery created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Delivery'

  /deliveries/{delivery_id}:
    parameters:
      - name: delivery_id
        in: path
        required: true
        schema:
          type: integer

    get:
      tags: [Deliveries]
      summary: Get Delivery Information
      description: Returns details for the specified delivery blueprint.
      operationId: getDelivery
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Delivery'

    delete:
      tags: [Deliveries]
      summary: Delete Delivery
      description: Deletes the specified delivery blueprint.
      operationId: deleteDelivery
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Delivery deleted

  # ==================== CONNECTIONS ====================
  /connections/types:
    get:
      tags: [Connections]
      summary: List Connection Types
      description: Returns the list of available connection types.
      operationId: listConnectionTypes
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConnectionType'

  /connections:
    get:
      tags: [Connections]
      summary: List Connections
      description: Returns all connections in the account.
      operationId: listConnections
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
        - name: type
          in: query
          description: Filter by connection type
          schema:
            type: string
        - name: connection_group_id
          in: query
          description: |
            Return only connections assigned to the given connection group. Pass the literal string `null` to return only connections that are **not** assigned to any connection group (the "ungrouped only" filter). Omit the parameter to return connections from every group.
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Connection'

    post:
      tags: [Connections]
      summary: Create Connection
      description: Creates a new connection to a data source or destination.
      operationId: createConnection
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectionCreate'
      responses:
        '201':
          description: Connection created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Connection'

  /connections/{connection_type}/{connection_id}:
    parameters:
      - name: connection_type
        in: path
        required: true
        description: The type of the connection (e.g., `sftp`, `mysql`, `salesforce`). Determines which connector schema the response is shaped against.
        schema:
          type: string
      - name: connection_id
        in: path
        required: true
        description: The numeric ID of the connection.
        schema:
          type: integer

    get:
      tags: [Connections]
      summary: Get Connection Information
      description: Returns details for the specified connection.
      operationId: getConnection
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Connection'
              example:
                id: 12345
                name: "Sample SFTP Connection"
                unique_id: "SFTP_CONNECTION_12345"
                created_at: "2026-01-01T00:00:00Z"
                updated_at: "2026-01-01T00:00:00Z"
                owner_id: 1000
                type: "sftp"
                url: "https://api.xplenty.com/{account}/api/connections/sftp/12345"
                port: 22
                auth_method: "password"
                host: "sftp.example.com"
                username: "your-username"
                tunnel_type: "direct"
                local_port: 12345

    put:
      tags: [Connections]
      summary: Update Connection
      description: Updates the specified connection's settings.
      operationId: updateConnection
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectionUpdate'
      responses:
        '200':
          description: Connection updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Connection'

    delete:
      tags: [Connections]
      summary: Delete Connection
      description: Deletes the specified connection.
      operationId: deleteConnection
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Connection deleted

  /connections/{connection_type}/{connection_id}/test:
    post:
      tags: [Connections]
      summary: Test Connection
      description: Tests the specified existing connection to verify it can connect.
      operationId: testConnection
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_type
          in: path
          required: true
          description: The type of the connection (e.g., `sftp`, `mysql`, `salesforce`).
          schema:
            type: string
        - name: connection_id
          in: path
          required: true
          description: The numeric ID of the connection to test.
          schema:
            type: integer
      responses:
        '200':
          description: Connection test result
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/ConnectionTestResult'

  /connections/{connection_type}/{connection_id}/validate:
    post:
      tags: [Connections]
      summary: Validate Connection
      description: Validates the specified connection's configuration.
      operationId: validateConnection
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_type
          in: path
          required: true
          description: The type of the connection (e.g., `sftp`, `mysql`, `salesforce`).
          schema:
            type: string
        - name: connection_id
          in: path
          required: true
          description: The numeric ID of the connection to validate.
          schema:
            type: integer
      responses:
        '200':
          description: Validation result
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: object

  /connections/test:
    post:
      tags: [Connections]
      summary: Test New Connection
      description: Tests a new connection before creating it.
      operationId: testNewConnection
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectionCreate'
      responses:
        '200':
          description: Connection test result
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/ConnectionTestResult'

  /connections/{connection_id}/schema:
    get:
      tags: [Connections]
      summary: Import Connection Schema
      description: Retrieves the schema (tables, columns) from the specified connection.
      operationId: importConnectionSchema
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Schema data
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: object

  # ==================== CONNECTION GROUPS ====================
  /connection_groups:
    get:
      tags: [Connection Groups]
      summary: List Connection Groups
      description: Returns all connection groups in the account. Each group includes the database and cloud storage connections assigned to it.
      operationId: listConnectionGroups
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConnectionGroup'

    post:
      tags: [Connection Groups]
      summary: Create Connection Group
      description: |
        Creates a new connection group. Pass an optional `connections` array to assign
        existing database and cloud storage connections to the group on creation.
        All referenced connections must belong to the same account.
      operationId: createConnectionGroup
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectionGroupCreate'
      responses:
        '201':
          description: Connection group created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/ConnectionGroup'

  /connection_groups/search:
    get:
      tags: [Connection Groups]
      summary: Search Connection Groups
      description: Searches connection groups in the account by name or description.
      operationId: searchConnectionGroups
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
        - name: q
          in: query
          required: true
          description: Search query.
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConnectionGroup'

  /connection_groups/{connection_group_id}:
    parameters:
      - name: connection_group_id
        in: path
        required: true
        description: The numeric ID of the connection group.
        schema:
          type: integer
    get:
      tags: [Connection Groups]
      summary: Get Connection Group
      description: Returns the specified connection group, including the connections assigned to it.
      operationId: getConnectionGroup
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/ConnectionGroup'

    put:
      tags: [Connection Groups]
      summary: Update Connection Group
      description: |
        Updates a connection group's name or description. Pass a `connections` array to
        replace the group's assigned connections. Connections not listed in the request
        are detached from the group; new ones are attached. Connections must belong to
        the same account as the group.
      operationId: updateConnectionGroup
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectionGroupUpdate'
      responses:
        '200':
          description: Connection group updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/ConnectionGroup'

    delete:
      tags: [Connection Groups]
      summary: Delete Connection Group
      description: Deletes the specified connection group. Connections previously assigned to it become ungrouped; the connections themselves are not deleted.
      operationId: deleteConnectionGroup
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Connection group deleted

  # ==================== ACCOUNTS ====================
  /accounts:
    get:
      tags: [Accounts]
      summary: List Accounts
      description: Returns accounts the authenticated user has access to.
      operationId: listAccounts
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Account'

    post:
      tags: [Accounts]
      summary: Create Account
      description: Creates a new Integrate.io account.
      operationId: createAccount
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountCreate'
      responses:
        '201':
          description: Account created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Account'

  /account:
    get:
      tags: [Accounts]
      summary: Get Current Account
      description: Returns the current account information.
      operationId: getAccount
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Account'

    put:
      tags: [Accounts]
      summary: Update Account
      description: Updates the current account's settings.
      operationId: updateAccount
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountUpdate'
      responses:
        '200':
          description: Account updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Account'

    delete:
      tags: [Accounts]
      summary: Delete Account
      description: Deletes the current account.
      operationId: deleteAccount
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Account deleted

  # ==================== MEMBERS ====================
  /members:
    get:
      tags: [Members]
      summary: List Account Members
      description: Returns all members of the current account.
      operationId: listMembers
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
        - name: role
          in: query
          description: Return only members assigned to the given predefined role.
          schema:
            type: string
        - name: custom_role_id
          in: query
          description: |
            Return only members assigned to the given custom role. Composes with `role` using AND semantics — passing both returns members who hold the predefined role **and** the custom role.
          schema:
            type: integer
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Member'

    post:
      tags: [Members]
      summary: Add Account Member
      description: Invites a new member to the current account with the specified role.
      operationId: addMember
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, role]
              properties:
                email:
                  type: string
                  format: email
                role:
                  type: string
                  enum: [admin, member, viewer]
      responses:
        '201':
          description: Member added
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Member'

  /members/{member_id}:
    parameters:
      - name: member_id
        in: path
        required: true
        schema:
          type: integer

    get:
      tags: [Members]
      summary: Get Account Member Information
      description: Returns details for the specified account member.
      operationId: getMember
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Member'

    put:
      tags: [Members]
      summary: Update Account Member Role
      description: Updates the role assigned to the specified account member.
      operationId: updateMemberRole
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [role]
              properties:
                role:
                  type: string
                  enum: [admin, member, viewer]
      responses:
        '200':
          description: Member role updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Member'

    delete:
      tags: [Members]
      summary: Remove Account Member
      description: Removes the specified member from the account.
      operationId: deleteMember
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Member removed

  # ==================== USERS ====================
  /user:
    get:
      tags: [Users]
      summary: Get Authenticated User Information
      description: Returns information about the currently authenticated user.
      operationId: getAuthenticatedUser
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/User'

    put:
      tags: [Users]
      summary: Update Authenticated User
      description: Updates the currently authenticated user's information.
      operationId: updateAuthenticatedUser
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserUpdate'
      responses:
        '200':
          description: User updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/User'

  /user/tokens:
    post:
      tags: [Users]
      summary: Regenerate Authenticated User Tokens
      description: Regenerates the API key for the authenticated user.
      operationId: regenerateTokens
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Tokens regenerated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/User'

  /user/password:
    post:
      tags: [Users]
      summary: Reset User Password
      description: Sends a password reset email to the specified address.
      operationId: resetPassword
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email]
              properties:
                email:
                  type: string
                  format: email
      responses:
        '200':
          description: Password reset email sent

  # ==================== PUBLIC KEYS ====================
  /user/keys:
    get:
      tags: [Public Keys]
      summary: List User Public Keys
      description: Returns the SSH public keys belonging to the authenticated user.
      operationId: listPublicKeys
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PublicKey'

    post:
      tags: [Public Keys]
      summary: Create Public Key
      description: Adds a new SSH public key for the authenticated user.
      operationId: createPublicKey
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, public_key]
              properties:
                name:
                  type: string
                public_key:
                  type: string
      responses:
        '201':
          description: Public key created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/PublicKey'

  /user/keys/{key_id}:
    parameters:
      - name: key_id
        in: path
        required: true
        schema:
          type: integer

    get:
      tags: [Public Keys]
      summary: Get Public Key Information
      description: Returns details for the specified SSH public key.
      operationId: getPublicKey
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/PublicKey'

    delete:
      tags: [Public Keys]
      summary: Delete Public Key
      description: Deletes the specified SSH public key.
      operationId: deletePublicKey
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Key deleted

  # ==================== NOTIFICATIONS ====================
  /notifications:
    get:
      tags: [Notifications]
      summary: List User Notifications
      description: Returns the authenticated user's notifications.
      operationId: listNotifications
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Notification'

  /notifications/mark:
    post:
      tags: [Notifications]
      summary: Mark Notifications as Read
      description: Marks one or all notifications as read.
      operationId: markNotificationsRead
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: integer
                  description: Mark a specific notification as read. Omit to mark all.
      responses:
        '200':
          description: Notifications marked as read

  # ==================== HOOKS ====================
  /hooks/types:
    get:
      tags: [Hooks]
      summary: List Hook Types
      description: Returns available webhook event types.
      operationId: listHookTypes
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /hooks:
    get:
      tags: [Hooks]
      summary: List Hooks
      description: Returns all webhooks in the account.
      operationId: listHooks
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Hook'

    post:
      tags: [Hooks]
      summary: Create Hook
      description: Creates a new webhook for event notifications.
      operationId: createHook
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HookCreate'
      responses:
        '201':
          description: Hook created
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Hook'

  /hooks/{hook_id}:
    parameters:
      - name: hook_id
        in: path
        required: true
        schema:
          type: integer

    get:
      tags: [Hooks]
      summary: Get Hook Information
      description: Returns details for the specified webhook.
      operationId: getHook
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Hook'

    put:
      tags: [Hooks]
      summary: Update Hook
      description: Updates the specified webhook's settings.
      operationId: updateHook
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HookUpdate'
      responses:
        '200':
          description: Hook updated
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Hook'

    delete:
      tags: [Hooks]
      summary: Delete Hook
      description: Deletes the specified webhook.
      operationId: deleteHook
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '204':
          description: Hook deleted

  /hooks/{hook_id}/ping:
    post:
      tags: [Hooks]
      summary: Ping Hook
      description: Sends a test ping to the specified webhook.
      operationId: pingHook
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: hook_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Ping sent

  /hooks/{hook_id}/reset:
    put:
      tags: [Hooks]
      summary: Reset Hook Salt
      description: Resets the signing salt for the specified webhook.
      operationId: resetHookSalt
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: hook_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Salt reset
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Hook'

  /hooks/search:
    get:
      tags: [Hooks]
      summary: Search Hooks
      description: Searches the account's webhooks.
      operationId: searchHooks
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: q
          in: query
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Hook'

  # ==================== SYSTEM ====================
  /regions:
    get:
      tags: [System]
      summary: List Available Regions
      description: Returns the regions available to Integrate.io.
      operationId: listRegions
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Region'

  /regions/account:
    get:
      tags: [System]
      summary: List Available Account Regions
      description: Returns the regions available to the current account.
      operationId: listAccountRegions
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Region'

  /stacks:
    get:
      tags: [System]
      summary: List Supported Stacks
      description: Returns the Hadoop stacks supported for clusters.
      operationId: listStacks
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    name:
                      type: string

  /variables:
    get:
      tags: [System]
      summary: List System Variables
      description: Returns the system variables available in expressions.
      operationId: listSystemVariables
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: object
                additionalProperties: true

  /timezones:
    get:
      tags: [System]
      summary: List Supported Time Zones
      description: Returns the time zones supported for scheduling.
      operationId: listTimezones
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: string

  /product_updates:
    get:
      tags: [System]
      summary: List Product Updates
      description: Returns recent Integrate.io product updates.
      operationId: listProductUpdates
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /rate_limit_status:
    get:
      tags: [System]
      summary: Get Rate Limit Status
      description: Returns current rate limit status. This call does not count against your rate limit.
      operationId: getRateLimitStatus
      security: []
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: object
                properties:
                  limits:
                    type: object
                    properties:
                      limit:
                        type: integer
                        example: 5000
                      remaining:
                        type: integer
                        example: 4999

  # ==================== BILLING ====================
  /payment_method:
    get:
      tags: [Billing]
      summary: Get Account Payment Method
      description: Returns the payment method on file for the current account.
      operationId: getPaymentMethod
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: object

  /subscription:
    get:
      tags: [Billing]
      summary: Get Subscription Information
      description: Returns the current account's subscription details.
      operationId: getSubscription
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: object

  /invoices:
    get:
      tags: [Billing]
      summary: List Invoices
      description: Returns the invoices for the current account.
      operationId: listInvoices
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Invoice'

  /invoices/{invoice_id}:
    get:
      tags: [Billing]
      summary: Get Invoice Information
      description: Returns details for the specified invoice.
      operationId: getInvoice
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: invoice_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                $ref: '#/components/schemas/Invoice'

  # ==================== THIRD-PARTY INTEGRATIONS ====================
  /connections/{connection_id}/salesforce/objects:
    get:
      tags: [Connections]
      summary: List Salesforce Objects
      description: Returns the Salesforce objects available through the specified connection.
      operationId: listSalesforceObjects
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Salesforce objects list
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /connections/{connection_id}/salesforce/fields:
    get:
      tags: [Connections]
      summary: List Salesforce Fields
      description: Returns the fields available on the specified Salesforce object.
      operationId: listSalesforceFields
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
        - name: object
          in: query
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Salesforce fields list
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /connections/{connection_id}/google_analytics/accounts:
    get:
      tags: [Connections]
      summary: List Google Analytics Accounts
      description: Returns the Google Analytics accounts available through the specified connection.
      operationId: listGoogleAnalyticsAccounts
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Google Analytics accounts
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /connections/{connection_id}/google_adwords/customers:
    get:
      tags: [Connections]
      summary: List Google AdWords Customers
      description: Returns the Google AdWords customers available through the specified connection.
      operationId: listGoogleAdWordsCustomers
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Google AdWords customers
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /connections/{connection_id}/facebook_ads_insights/accounts:
    get:
      tags: [Connections]
      summary: List Facebook Ads Insights Accounts
      description: Returns the Facebook Ads Insights accounts available through the specified connection.
      operationId: listFacebookAdsAccounts
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Facebook Ads accounts
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /connections/{connection_id}/facebook_ads_insights/fields:
    get:
      tags: [Connections]
      summary: List Facebook Ads Insights Fields
      description: Returns the Facebook Ads Insights fields available through the specified connection.
      operationId: listFacebookAdsFields
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Facebook Ads fields
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /connections/{connection_id}/bingads/accounts:
    get:
      tags: [Connections]
      summary: List Bing Ads Accounts
      description: Returns the Bing Ads accounts available through the specified connection.
      operationId: listBingAdsAccounts
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Bing Ads accounts
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  /connections/{connection_id}/bingads/columns:
    get:
      tags: [Connections]
      summary: List Bing Ads Columns
      description: Returns the Bing Ads columns available through the specified connection.
      operationId: listBingAdsColumns
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - name: connection_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Bing Ads columns
          content:
            application/vnd.xplenty+json; version=2:
              schema:
                type: array
                items:
                  type: object

  # ==================== WATCHERS ====================
  /clusters/{cluster_id}/watchers:
    post:
      tags: [Clusters]
      summary: Watch Cluster
      description: Subscribe to notifications for the specified cluster.
      operationId: watchCluster
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/clusterIdParam'
      responses:
        '200':
          description: Now watching cluster

  /jobs/{job_id}/watchers:
    post:
      tags: [Jobs]
      summary: Watch Job
      description: Subscribe to notifications for the specified job.
      operationId: watchJob
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/jobIdParam'
      responses:
        '200':
          description: Now watching job

  /schedules/{schedule_id}/watchers:
    post:
      tags: [Schedules]
      summary: Watch Schedule
      description: Subscribe to notifications for the specified schedule.
      operationId: watchSchedule
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
        - $ref: '#/components/parameters/scheduleIdParam'
      responses:
        '200':
          description: Now watching schedule

  /help:
    get:
      tags: [System]
      summary: Help
      description: Returns API help information and available endpoints.
      operationId: getHelp
      security: []
      parameters:
        - $ref: '#/components/parameters/acceptHeader'
      responses:
        '200':
          description: API help information

# ==============================================================================
# COMPONENTS
# ==============================================================================
components:
  securitySchemes:
    apiKeyAuth:
      type: http
      scheme: basic
      description: |
        Enter your API key as the username. Leave the password field blank.
        Example: `curl -u YOUR_API_KEY: https://api.xplenty.com/...`

  parameters:
    acceptHeader:
      name: Accept
      in: header
      required: true
      description: API version header — required on all requests
      schema:
        type: string
        default: "application/vnd.xplenty+json; version=2"

    offsetParam:
      name: offset
      in: query
      description: Index of the first object to retrieve (starting from 0)
      schema:
        type: integer
        minimum: 0
        default: 0

    limitParam:
      name: limit
      in: query
      description: Number of items to return (max 100)
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20

    clusterIdParam:
      name: cluster_id
      in: path
      required: true
      description: The unique ID of the cluster
      schema:
        type: integer

    jobIdParam:
      name: job_id
      in: path
      required: true
      description: The unique ID of the job
      schema:
        type: integer

    packageIdParam:
      name: package_id
      in: path
      required: true
      description: The unique ID of the package
      schema:
        type: integer

    scheduleIdParam:
      name: schedule_id
      in: path
      required: true
      description: The unique ID of the schedule
      schema:
        type: integer

  headers:
    LinkPagination:
      description: Pagination links (RFC 5988)
      schema:
        type: string
        example: '<https://api.xplenty.com/account/api/clusters?offset=2&limit=10>; rel="next"'

  responses:
    BadRequest:
      description: Invalid request
      content:
        application/vnd.xplenty+json; version=2:
          schema:
            $ref: '#/components/schemas/Error'

    Unauthorized:
      description: Invalid or missing credentials
      content:
        application/vnd.xplenty+json; version=2:
          schema:
            $ref: '#/components/schemas/Error'

    PaymentRequired:
      description: Billing information required
      content:
        application/vnd.xplenty+json; version=2:
          schema:
            $ref: '#/components/schemas/Error'

    NotFound:
      description: Resource not found
      content:
        application/vnd.xplenty+json; version=2:
          schema:
            $ref: '#/components/schemas/Error'

    UnprocessableEntity:
      description: Invalid fields provided
      content:
        application/vnd.xplenty+json; version=2:
          schema:
            $ref: '#/components/schemas/Error'

    TooManyRequests:
      description: Rate limit exceeded
      content:
        application/vnd.xplenty+json; version=2:
          schema:
            $ref: '#/components/schemas/Error'

  schemas:
    Error:
      type: object
      properties:
        message:
          type: string
          example: "Item not found."

    # ---- CLUSTER ----
    Cluster:
      type: object
      properties:
        id:
          type: integer
          example: 99
        name:
          type: string
          example: "Daily Outliers Test #100"
        description:
          type: string
          example: "Daily Outliers Test"
        status:
          type: string
          enum: [pending, creating, available, scaling, pending_terminate, terminating, terminated, error]
          example: "available"
        owner_id:
          type: integer
          example: 27
        plan_id:
          type: integer
          nullable: true
        nodes:
          type: integer
          example: 2
        type:
          type: string
          enum: [sandbox, production]
          example: "production"
        created_at:
          type: string
          format: date-time
          example: "2013-01-25T08:18:39Z"
        updated_at:
          type: string
          format: date-time
          example: "2013-01-28T16:45:24Z"
        available_since:
          type: string
          format: date-time
          nullable: true
        terminated_at:
          type: string
          format: date-time
          nullable: true
        running_jobs_count:
          type: integer
          example: 0
        terminate_on_idle:
          type: boolean
          example: false
        time_to_idle:
          type: integer
          description: Seconds of inactivity before auto-termination
          example: 3600
        terminated_on_idle:
          type: boolean
          example: false
        region:
          type: string
          example: "amazon-web-services::us-east-1"
        zone:
          type: string
          example: "us-east-1b"
        master_instance_type:
          type: string
          example: "m3.xlarge"
        slave_instance_type:
          type: string
          example: "m3.xlarge"
        master_spot_price:
          type: number
          nullable: true
        slave_spot_price:
          type: number
          nullable: true
        master_spot_percentage:
          type: number
          nullable: true
        slave_spot_percentage:
          type: number
          nullable: true
        allow_fallback:
          type: boolean
          example: true
        stack:
          type: string
          example: "white-everest"
        idle_since:
          type: string
          format: date-time
          nullable: true
        url:
          type: string
          format: uri
          example: "https://api.xplenty.com/xplenation/api/clusters/99"
        html_url:
          type: string
          format: uri
          example: "https://xplenty.com/xplenation/clusters/99"
        creator:
          type: object
          properties:
            type:
              type: string
            display_name:
              type: string
            id:
              type: integer
            url:
              type: string
              format: uri

    ClusterCreate:
      type: object
      required: [nodes, type]
      properties:
        name:
          type: string
          description: Cluster name
        description:
          type: string
          description: Cluster description
        type:
          type: string
          enum: [sandbox, production]
          description: Cluster type
        nodes:
          type: integer
          minimum: 1
          description: Number of compute nodes
        region:
          type: string
          description: Cloud region identifier
        zone:
          type: string
          description: Availability zone
        master_instance_type:
          type: string
        slave_instance_type:
          type: string
        master_spot_price:
          type: number
        slave_spot_price:
          type: number
        master_spot_percentage:
          type: number
        slave_spot_percentage:
          type: number
        allow_fallback:
          type: boolean
        stack:
          type: string
        terminate_on_idle:
          type: boolean
          description: Automatically terminate when idle
        time_to_idle:
          type: integer
          description: Seconds of inactivity before auto-termination

    ClusterUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        nodes:
          type: integer
        terminate_on_idle:
          type: boolean
        time_to_idle:
          type: integer

    # ---- JOB ----
    Job:
      type: object
      properties:
        id:
          type: integer
          example: 157
        status:
          type: string
          enum: [idle, pending, queued, running, completed, failed, pending_stoppage, stopping, stopped]
          example: "completed"
        owner_id:
          type: integer
        progress:
          type: number
          format: double
          minimum: 0
          maximum: 1
          example: 1.0
        outputs_count:
          type: integer
          example: 2
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/JobOutput'
        variables:
          type: object
          additionalProperties: true
        dynamic_variables:
          type: object
          additionalProperties: true
        started_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
        failed_at:
          type: string
          format: date-time
          nullable: true
        updated_at:
          type: string
          format: date-time
        cluster_id:
          type: integer
          example: 52
        package_id:
          type: integer
          example: 434
        errors:
          type: string
        runtime_in_seconds:
          type: integer
        url:
          type: string
          format: uri
        html_url:
          type: string
          format: uri
        log_url:
          type: string
          format: uri
          nullable: true
        creator:
          type: object
          properties:
            type:
              type: string
            display_name:
              type: string
            id:
              type: integer
            url:
              type: string
              format: uri
        package:
          type: object
          properties:
            id:
              type: integer
            name:
              type: string
            url:
              type: string
              format: uri
        cluster:
          type: object
          properties:
            id:
              type: integer
            name:
              type: string
            url:
              type: string
              format: uri

    JobOutput:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
          example: "projected_results"
        records_count:
          type: integer
          example: 10415234
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        url:
          type: string
          format: uri
        component:
          type: object
          properties:
            name:
              type: string
            type:
              type: string
            fields:
              type: array
              items:
                type: string

    JobCreate:
      type: object
      required: [cluster_id, package_id]
      properties:
        cluster_id:
          type: integer
          description: ID of the cluster to run on
        package_id:
          type: integer
          description: ID of the package to execute
        variables:
          type: object
          additionalProperties:
            type: string
          description: Static variables for the job
        dynamic_variables:
          type: object
          additionalProperties:
            type: string
          description: Dynamic variables (evaluated at runtime)

    # ---- PACKAGE ----
    Package:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
        variables:
          type: object
          additionalProperties: true
        owner_id:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        url:
          type: string
          format: uri
        html_url:
          type: string
          format: uri
        status:
          type: string

    PackageCreate:
      type: object
      required: [name]
      properties:
        name:
          type: string
        description:
          type: string
        flow_type:
          type: string
        raw_data:
          type: object

    PackageUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        flow_type:
          type: string
        raw_data:
          type: object

    PackageValidation:
      type: object
      properties:
        id:
          type: integer
        status:
          type: string
          enum: [running, completed, failed]
        errors:
          type: array
          items:
            type: object
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        package_id:
          type: integer

    # ---- SCHEDULE ----
    Schedule:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
        status:
          type: string
          enum: [enabled, disabled]
        owner_id:
          type: integer
        start_at:
          type: string
          format: date-time
        next_run_at:
          type: string
          format: date-time
          nullable: true
        interval_amount:
          type: integer
        interval_unit:
          type: string
          enum: [minutes, hours, days, weeks, months]
        task:
          type: object
          properties:
            nodes:
              type: integer
            packages:
              type: array
              items:
                type: object
                properties:
                  package_id:
                    type: integer
                  variables:
                    type: object
                    additionalProperties: true
        overlap:
          type: boolean
        reuse_cluster:
          type: boolean
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        url:
          type: string
          format: uri
        html_url:
          type: string
          format: uri

    ScheduleCreate:
      type: object
      required: [name, start_at, interval_amount, interval_unit, task]
      properties:
        name:
          type: string
        description:
          type: string
        status:
          type: string
          enum: [enabled, disabled]
        start_at:
          type: string
          format: date-time
        interval_amount:
          type: integer
        interval_unit:
          type: string
          enum: [minutes, hours, days, weeks, months]
        task:
          type: object
          required: [nodes, packages]
          properties:
            nodes:
              type: integer
            packages:
              type: array
              items:
                type: object
                required: [package_id]
                properties:
                  package_id:
                    type: integer
                  variables:
                    type: object
                    additionalProperties: true
        overlap:
          type: boolean
        reuse_cluster:
          type: boolean

    ScheduleUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        status:
          type: string
          enum: [enabled, disabled]
        start_at:
          type: string
          format: date-time
        interval_amount:
          type: integer
        interval_unit:
          type: string
          enum: [minutes, hours, days, weeks, months]
        task:
          type: object
        overlap:
          type: boolean
        reuse_cluster:
          type: boolean

    # ---- DELIVERY ----
    Delivery:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
        status:
          type: string
        source:
          type: object
        destination:
          type: object
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        url:
          type: string
          format: uri

    DeliveryCreate:
      type: object
      required: [name]
      properties:
        name:
          type: string
        description:
          type: string
        source:
          type: object
        destination:
          type: object

    # ---- CONNECTION ----
    ConnectionType:
      type: object
      properties:
        type:
          type: string
        name:
          type: string
        description:
          type: string
        icon_url:
          type: string
          format: uri
        groups:
          type: array
          items:
            type: string

    Connection:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        type:
          type: string
        connection_group_id:
          type: integer
          nullable: true
          description: ID of the connection group this connection belongs to, or `null` if ungrouped.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        url:
          type: string
          format: uri

    ConnectionCreate:
      type: object
      required: [name, type]
      properties:
        name:
          type: string
        type:
          type: string
          description: Connection type identifier

    ConnectionUpdate:
      type: object
      properties:
        name:
          type: string

    ConnectionTestResult:
      type: object
      properties:
        status:
          type: string
          enum: [success, failure]
        message:
          type: string

    # ---- CONNECTION GROUP ----
    ConnectionGroup:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
          nullable: true
        account_id:
          type: integer
        modified_by:
          type: object
          description: User who last modified the group.
          properties:
            name:
              type: string
            email:
              type: string
        connections:
          type: array
          description: Database and cloud storage connections assigned to this group.
          items:
            type: object
            properties:
              id:
                type: integer
              name:
                type: string
              type:
                type: string
                description: Short connection type identifier (for example, `mysql`, `s3`).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    ConnectionGroupCreate:
      type: object
      required: [connection_group]
      properties:
        connection_group:
          type: object
          required: [name]
          properties:
            name:
              type: string
            description:
              type: string
        connections:
          type: array
          description: Connections to attach to the new group.
          items:
            type: object
            required: [id, type]
            properties:
              id:
                type: integer
              type:
                type: string
                description: Connection type identifier (for example, `mysql`, `s3`).

    ConnectionGroupUpdate:
      type: object
      properties:
        connection_group:
          type: object
          properties:
            name:
              type: string
            description:
              type: string
        connections:
          type: array
          description: Replacement set of connections for the group. Omit to leave assignments unchanged.
          items:
            type: object
            required: [id, type]
            properties:
              id:
                type: integer
              type:
                type: string

    # ---- ACCOUNT ----
    Account:
      type: object
      properties:
        id:
          type: integer
        account_id:
          type: string
        name:
          type: string
        uname:
          type: string
        region:
          type: string
        location:
          type: string
        billing_email:
          type: string
          format: email
        gravatar_email:
          type: string
          format: email
        avatar_url:
          type: string
          format: uri
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        connections_count:
          type: integer
        role:
          type: string
        owner_id:
          type: integer
        members_count:
          type: integer
        packages_count:
          type: integer
        jobs_count:
          type: integer
        running_jobs_count:
          type: integer
        url:
          type: string
          format: uri
        public_key:
          type: string

    AccountCreate:
      type: object
      required: [name]
      properties:
        name:
          type: string
        region:
          type: string
        location:
          type: string

    AccountUpdate:
      type: object
      properties:
        name:
          type: string
        region:
          type: string
        location:
          type: string
        billing_email:
          type: string
          format: email
        gravatar_email:
          type: string
          format: email

    # ---- MEMBER ----
    Member:
      type: object
      properties:
        id:
          type: integer
        display_name:
          type: string
        email:
          type: string
          format: email
        role:
          type: string
          enum: [admin, member, viewer]
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        avatar_url:
          type: string
          format: uri
        url:
          type: string
          format: uri
        html_url:
          type: string
          format: uri

    # ---- USER ----
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          format: email
        avatar_url:
          type: string
          format: uri
        api_key:
          type: string
        time_zone:
          type: string
        location:
          type: string
        confirmed:
          type: boolean
        confirmed_at:
          type: string
          format: date-time
          nullable: true
        notifications_count:
          type: integer
        unread_notifications_count:
          type: integer
        notification_settings:
          type: object
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        url:
          type: string
          format: uri
        html_url:
          type: string
          format: uri
        last_login:
          type: string
          format: date-time
          nullable: true

    UserUpdate:
      type: object
      properties:
        name:
          type: string
        email:
          type: string
          format: email
        time_zone:
          type: string
        location:
          type: string
        notification_settings:
          type: object

    # ---- PUBLIC KEY ----
    PublicKey:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        fingerprint:
          type: string
        comment:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        url:
          type: string
          format: uri

    # ---- NOTIFICATION ----
    Notification:
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        body:
          type: string
        read:
          type: boolean
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    # ---- HOOK ----
    Hook:
      type: object
      properties:
        id:
          type: integer
        type:
          type: string
        name:
          type: string
        active:
          type: boolean
        settings:
          type: object
        events:
          type: array
          items:
            type: string
        salt:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        url:
          type: string
          format: uri

    HookCreate:
      type: object
      required: [type, name, settings, events]
      properties:
        type:
          type: string
        name:
          type: string
        active:
          type: boolean
          default: true
        settings:
          type: object
          description: Hook-type-specific settings (e.g., URL for web hooks)
        events:
          type: array
          items:
            type: string
          description: Events to subscribe to

    HookUpdate:
      type: object
      properties:
        name:
          type: string
        active:
          type: boolean
        settings:
          type: object
        events:
          type: array
          items:
            type: string

    # ---- REGION ----
    Region:
      type: object
      properties:
        id:
          type: string
          example: "amazon-web-services::us-east-1"
        name:
          type: string
          example: "AWS - US East (N. Virginia)"
        group_name:
          type: string
          example: "Amazon Web Services"

    # ---- INVOICE ----
    Invoice:
      type: object
      properties:
        id:
          type: string
        date:
          type: string
          format: date
        amount:
          type: number
        currency:
          type: string
        status:
          type: string
        pdf_url:
          type: string
          format: uri
