openapi: 3.1.1
info:
  title: Tenant Management API
  version: 1.0.0
  description: 'Combined specification for Tenant Management v1: tenants, hosts, and tenancy access controls
    (role groups and roles).


    Paths are rooted at the API host (see `servers`). Tenant and host operations use the `/tenant-man/v1`
    prefix; access control operations use `/tenant-man/access-controls/v1`.'
  contact:
    name: Gradera Platform Team
    email: platform-team@gradera.ai
    url: https://gradera.ai
servers:
- url: https://dev.apis.gradera.ai
  description: Development server
- url: https://qa.apis.gradera.ai
  description: Quality Assurance server
- url: https://stage.apis.gradera.ai
  description: Staging server
- url: https://cte.apis.gradera.ai
  description: Consumer Test Environment server
- url: https://apis.gradera.ai
  description: Production server
security:
- oauth2: []
tags:
- name: Tenants
  description: Operations for managing tenants.
- name: Hosts
  description: Operations related to hosts.
- name: RoleGroups
  description: Operations related to role groups.
- name: Roles
  description: Operations related to roles.
paths:
  /tenant-man/access-controls/v1/roleGroups:
    get:
      operationId: listRoleGroups
      summary: List all role groups
      description: Retrieve an unpaginated list of all role groups, sorted alphabetically.
      tags:
      - RoleGroups
      parameters: []
      responses:
        '200':
          description: A list of role groups.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                type: object
                properties:
                  RoleGroups:
                    type: array
                    items:
                      $ref: '#/components/schemas/RoleGroup'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createRoleGroup
      summary: Create a new role group
      description: Create a new role group with a name and description.
      tags:
      - RoleGroups
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleGroupCreate'
      responses:
        '201':
          description: Role group created successfully.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleGroup'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /tenant-man/access-controls/v1/roleGroups/{roleGroupId}:
    parameters:
    - $ref: '#/components/parameters/roleGroupId'
    put:
      operationId: updateRoleGroup
      summary: Update a role group
      description: Update a role group by providing a new name and description.
      tags:
      - RoleGroups
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleGroupCreate'
      responses:
        '200':
          description: Role group updated successfully.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleGroup'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteRoleGroup
      summary: Delete a role group
      description: Delete a role group. This will fail if the role group has associated roles.
      tags:
      - RoleGroups
      responses:
        '204':
          description: Role group deleted successfully.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /tenant-man/access-controls/v1/roleGroups/{roleGroupId}/roles:
    parameters:
    - $ref: '#/components/parameters/roleGroupId'
    get:
      operationId: listRolesForGroup
      summary: List roles for a role group
      description: Retrieve a list of active roles for a specific role group.
      tags:
      - Roles
      responses:
        '200':
          description: A list of roles for the specified group.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Role'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createRoleForGroup
      summary: Create a new role for a group
      description: Create a new role within a specific role group.
      tags:
      - Roles
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleCreate'
      responses:
        '201':
          description: Role created successfully.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /tenant-man/access-controls/v1/roles/{roleId}:
    parameters:
    - $ref: '#/components/parameters/roleId'
    put:
      operationId: updateRole
      summary: Update a role
      description: Update a role's details.
      tags:
      - Roles
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleUpdate'
      responses:
        '200':
          description: Role updated successfully.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteRole
      summary: Delete a role
      description: Deletes a role by changing its status to inactive.
      tags:
      - Roles
      responses:
        '204':
          description: Role deleted successfully.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /tenant-man/v1/hosts:
    get:
      operationId: listHosts
      summary: List all hosts
      description: Retrieves a paginated list of all hosts.
      tags:
      - Hosts
      parameters:
      - $ref: '#/components/parameters/offset'
      - $ref: '#/components/parameters/limit'
      responses:
        '200':
          description: A paginated list of hosts.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Host'
                  paging:
                    $ref: '#/components/schemas/Paging'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createHost
      summary: Create a new host
      description: Creates a new host resource.
      tags:
      - Hosts
      requestBody:
        $ref: '#/components/requestBodies/HostCreate'
      responses:
        '201':
          description: Host created successfully.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Host'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /tenant-man/v1/hosts/{hostId}:
    parameters:
    - $ref: '#/components/parameters/hostId'
    get:
      operationId: getHostById
      summary: Get a host by ID
      description: Retrieves a single host resource by its ID.
      tags:
      - Hosts
      responses:
        '200':
          description: The host resource.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Host'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      operationId: updateHost
      summary: Update a host
      description: Updates an existing host resource.
      tags:
      - Hosts
      requestBody:
        $ref: '#/components/requestBodies/HostCreate'
      responses:
        '200':
          description: Host updated successfully.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Host'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteHost
      summary: Delete a host
      description: Deletes a host resource if it has no relationships.
      tags:
      - Hosts
      responses:
        '204':
          description: Host deleted successfully.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /tenant-man/v1/tenants:
    get:
      tags:
      - Tenants
      summary: List or Search Tenants
      description: Retrieves a paginated list of tenants. The list can be filtered by `name` or `companyName`.
      operationId: listTenants
      parameters:
      - $ref: '#/components/parameters/name'
      - $ref: '#/components/parameters/companyName'
      - $ref: '#/components/parameters/offset'
      - $ref: '#/components/parameters/limit'
      responses:
        '200':
          description: A paginated list of tenants.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Tenant'
                  paging:
                    $ref: '#/components/schemas/Paging'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      tags:
      - Tenants
      summary: Create Tenant
      description: Creates a new tenant.
      operationId: createTenant
      requestBody:
        $ref: '#/components/requestBodies/TenantCreate'
      responses:
        '201':
          description: Tenant created successfully.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tenant'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /tenant-man/v1/tenants/{tenantId}:
    parameters:
    - $ref: '#/components/parameters/tenantId'
    get:
      tags:
      - Tenants
      summary: Get Tenant by ID
      description: Retrieves a single tenant by its unique identifier.
      operationId: getTenantById
      parameters:
      - name: Prefer
        in: header
        description: Used to request a minimal representation of the tenant resource. Set to `return=minimal`
          to receive a subset of fields.
        schema:
          type: string
          example: return=minimal
      responses:
        '200':
          description: The tenant resource.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tenant'
              examples:
                full:
                  summary: Full Tenant Representation
                  value:
                    tenantId: 9b9786e1-13ca-47f3-ab9c-7e1f252917aa
                    cname: niq://gradera/tenant/acme-pets
                    slug: acme-pets
                    name: ACME Pet Store
                    companyName: ACME Pet Store, Inc.
                    companyDUNS: '064557655'
                    description: ACME Pet Store Product Management team.
                    customDomain: acme-pets.flow-studio.ai
                    hostId: 2d646848-255a-4229-b634-8365df48b004
                    host:
                      hostId: 2d646848-255a-4229-b634-8365df48b004
                      cloudProvider: GCP
                      name: Shared US Central 1
                      hostIPv4: 127.1.1.199
                      hostIPv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
                      domain: 2HA232C.platform.gradera.ai
                minimal:
                  summary: Minimal Tenant Representation (example shaped for Prefer return=minimal; still matches Tenant schema)
                  value:
                    tenantId: 9b9786e1-13ca-47f3-ab9c-7e1f252917aa
                    cname: niq://gradera/tenant/acme-pets
                    slug: acme-pets
                    name: ACME Pet Store
                    companyName: ACME Pet Store, Inc.
                    companyDUNS: '064557655'
                    description: ACME Pet Store Product Management team.
                    customDomain: acme-pets.flow-studio.ai
                    hostId: 2d646848-255a-4229-b634-8365df48b004
                    host:
                      hostId: 2d646848-255a-4229-b634-8365df48b004
                      cloudProvider: GCP
                      name: Shared US Central 1
                      hostIPv4: 127.1.1.199
                      hostIPv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
                      domain: 2HA232C.platform.gradera.ai
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      tags:
      - Tenants
      summary: Update Tenant
      description: Updates an existing tenant's properties.
      operationId: updateTenant
      requestBody:
        $ref: '#/components/requestBodies/TenantUpdate'
      responses:
        '200':
          description: Tenant updated successfully.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tenant'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      tags:
      - Tenants
      summary: Delete Tenant
      description: Deletes a tenant by its unique identifier.
      operationId: deleteTenant
      responses:
        '204':
          description: The tenant was deleted successfully.
          headers:
            API-Version:
              $ref: '#/components/headers/API-Version'
            Correlation-Key:
              $ref: '#/components/headers/Correlation-Key'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  schemas:
    RoleGroupCreate:
      type: object
      description: The properties required to create or update a role group.
      properties:
        name:
          type: string
          description: The human-readable name of the role group.
          minLength: 1
          maxLength: 100
          examples:
          - Users & Groups
        description:
          type: string
          description: A detailed explanation of the role group's purpose.
          minLength: 1
          maxLength: 255
          examples:
          - The management of users and groups for the tenancy.
      required:
      - name
      - description
    RoleGroup:
      title: Role Group
      description: Represents a logical grouping of roles within a tenancy.
      allOf:
      - $ref: '#/components/schemas/RoleGroupCreate'
      - type: object
        properties:
          roleGroupId:
            type: string
            description: The universally unique identifier for the role group.
            format: uuid
            pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
            readOnly: true
            examples:
            - 1bfc687b-0fd4-42a7-9668-8638710695bc
        required:
        - roleGroupId
    RoleCreate:
      type: object
      description: The properties required to create or update a role.
      properties:
        role:
          type: string
          description: The machine-readable name of the role.
          minLength: 1
          maxLength: 100
          examples:
          - users-admin
        description:
          type: string
          description: A human-readable explanation of the role's purpose and permissions.
          minLength: 1
          maxLength: 256
          examples:
          - Full administrative rights to invite, remove, and permission users for the tenancy
        entityType:
          type: string
          description: Use this field if this role pertains to a specific permission granted for an entity
            to a user.
          enum:
          - flow
          - report
          - group
      required:
      - role
      - description
    RoleUpdate:
      type: object
      description: The properties that can be updated for a role.
      allOf:
        - $ref: '#/components/schemas/RoleCreate'
        - type: object
          properties:
            status:
              type: string
              description: The current status of the role.
              enum:
                - active
                - inactive
          required:
            - description
    Role:
      title: Role
      description: Defines a role within the system, granting specific permissions to users.
      allOf:
      - $ref: '#/components/schemas/RoleCreate'
      - type: object
        properties:
          roleId:
            type: string
            description: The universally unique identifier for the role.
            format: uuid
            pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
            readOnly: true
            examples:
            - 6d05c461-0b36-46ab-b156-937c86b6fe73
          roleGroup:
            type: string
            description: The group or category this role belongs to.
            minLength: 1
            maxLength: 100
            readOnly: true
            examples:
            - Users & Groups
        required:
        - roleId
        - roleGroup
    Error:
      type: object
      required:
      - id
      - code
      - title
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for this error occurrence.
          examples:
          - 8eaeac83-edd8-4977-880d-053b42e827e0
          readOnly: true
        code:
          type: string
          description: Application-specific error code.
          examples:
          - XB400
        title:
          type: string
          description: Short, localizable summary of the problem.
          examples:
          - Invalid query parameter
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence.
          examples:
          - The 'limit' parameter must be between 1 and 100.
      description: A structured error object.
    Errors:
      type: array
      items:
        $ref: '#/components/schemas/Error'
      description: An array of error objects.
    TenantBase:
      type: object
      description: The properties required to create a new tenant.
      required:
      - slug
      - name
      - description
      - companyName
      - companyDUNS
      - customDomain
      - hostId
      properties:
        slug:
          type: string
          description: A URL-safe, human-readable identifier for the tenant, expressed in kebab-case.
            Used in routing and resource addressing.
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          minLength: 1
          maxLength: 100
          examples:
          - acme-pets
        name:
          type: string
          description: The display name of the tenant as shown in the platform UI.
          minLength: 1
          maxLength: 150
          examples:
          - ACME Pet Store
        description:
          type: string
          description: A human-readable description of the tenant's purpose or business context.
          minLength: 1
          maxLength: 256
          examples:
          - ACME Pet Store Product Management team.
        companyName:
          type: string
          description: The legal registered company name of the tenant organisation.
          minLength: 1
          maxLength: 150
          examples:
          - ACME Pet Store, Inc.
        companyDUNS:
          type: string
          description: The nine-digit Dun & Bradstreet Data Universal Numbering System (DUNS) identifier
            for the tenant's registered company.
          pattern: ^[0-9]{9}$
          examples:
          - '064557655'
        customDomain:
          type: string
          description: The custom hostname configured for the tenant's Flow Studio instance.
          format: hostname
          minLength: 1
          maxLength: 150
          examples:
          - acme-pets.flow-studio.ai
    TenantCreate:
      title: TenantCreate
      description: The properties required to create a new tenant.
      allOf:
      - $ref: '#/components/schemas/TenantBase'
      - type: object
        required:
        - hostId
        properties:
          hostId:
            type: string
            format: uuid
            description: The unique identifier of the host to associate with the tenant.
            examples:
            - 2d646848-255a-4229-b634-8365df48b004
    Tenant:
      title: Tenant
      description: Represents a tenant within the Gradera platform. Tenants are top-level organisational
        units that own resources such as users, flows, and configurations. Each tenant maps to a single
        company or team and is assigned to a host environment.
      allOf:
      - $ref: '#/components/schemas/TenantBase'
      - type: object
        required:
        - tenantId
        - cname
        - host
        properties:
          tenantId:
            type: string
            description: The universally unique identifier for the tenant.
            format: uuid
            pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
            readOnly: true
            examples:
            - 9b9786e1-13ca-47f3-ab9c-7e1f252917aa
          cname:
            type: string
            description: The canonical resource name (CNAME) for the tenant within the Gradera platform,
              expressed as a URI.
            format: uri
            readOnly: true
            examples:
            - niq://gradera/tenant/acme-pets
          host:
            $ref: '#/components/schemas/Host'
    Host:
      title: Host
      description: Represents a host, which is a platform computing environment at a cloud provider.
      allOf:
      - $ref: '#/components/schemas/HostCreate'
      - type: object
        properties:
          hostId:
            type: string
            description: The universally unique identifier for the host.
            format: uuid
            pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
            examples:
            - a882daaf-2bf4-4371-a570-380efa6d12d8
            readOnly: true
        required:
        - hostId
    Paging:
      type: object
      description: Pagination metadata for the result set.
      required:
      - offset
      - limit
      - total
      - _links
      properties:
        offset:
          type: integer
          description: Number of records skipped.
          examples:
          - 0
        limit:
          type: integer
          description: Number of records returned in this page.
          examples:
          - 25
        total:
          type: integer
          description: Total number of matching records across all pages.
          examples:
          - 47
        _links:
          type: object
          description: HATEOAS navigation links for pagination.
          properties:
            self:
              type: string
              format: uri
              examples:
              - https://apis.gradera.ai/tenant-man/v1/hosts?offset=25&limit=25
            first:
              type: string
              format: uri
              examples:
              - https://apis.gradera.ai/tenant-man/v1/hosts?offset=0&limit=25
            prev:
              type: string
              format: uri
              examples:
              - https://apis.gradera.ai/tenant-man/v1/hosts?offset=0&limit=25
            next:
              type: string
              format: uri
              examples:
              - https://apis.gradera.ai/tenant-man/v1/hosts?offset=50&limit=25
            last:
              type: string
              format: uri
              examples:
              - https://apis.gradera.ai/tenant-man/v1/hosts?offset=25&limit=25
    HostCreate:
      type: object
      description: The properties required to create or update a host.
      properties:
        cloudProvider:
          type: string
          description: The cloud provider where the host is located.
          enum:
          - GCP
          - AWS
          - Azure
          - Other
          examples:
          - AWS
        name:
          type: string
          description: A human-readable name for the host.
          minLength: 1
          maxLength: 100
          examples:
          - Shared US Central 1
        description:
          type: string
          description: A human-readable description for the host.
          minLength: 1
          maxLength: 256
          examples:
          - The hosting used for demo and customer POCs
        hostIPv4:
          type: string
          description: The IPv4 address of the host.
          format: ipv4
          examples:
          - 127.1.1.199
        hostIPv6:
          type: string
          description: The IPv6 address of the host.
          format: ipv6
          examples:
          - 2001:0db8:85a3:0000:0000:8a2e:0370:7334
        domain:
          type: string
          description: The domain name associated with the host.
          format: hostname
          examples:
          - 2HA232C.platform.gradera.ai
      required:
      - cloudProvider
      - name
      - hostIPv4
      - hostIPv6
      - domain
  parameters:
    roleGroupId:
      name: roleGroupId
      in: path
      required: true
      description: The universally unique identifier for the role group.
      schema:
        type: string
        format: uuid
    roleId:
      name: roleId
      in: path
      required: true
      description: The universally unique identifier for the role.
      schema:
        type: string
        format: uuid
    tenantId:
      name: tenantId
      in: path
      required: true
      description: The unique identifier of the tenant.
      schema:
        type: string
        format: uuid
    name:
      name: name
      in: query
      description: Filter tenants by a full or partial match on the name field.
      schema:
        type: string
    companyName:
      name: companyName
      in: query
      description: Filter tenants by a full or partial match on the company name field.
      schema:
        type: string
    offset:
      name: offset
      in: query
      description: The number of items to skip before starting to collect the result set.
      schema:
        type: integer
        minimum: 0
        default: 0
      required: false
    limit:
      name: limit
      in: query
      description: The numbers of items to return.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 25
      required: false
    hostId:
      name: hostId
      in: path
      required: true
      description: The universally unique identifier for the host.
      schema:
        type: string
        format: uuid
  responses:
    BadRequest:
      description: Bad Request - The server could not understand the request due to invalid syntax.
      headers:
        API-Version:
          $ref: '#/components/headers/API-Version'
        Correlation-Key:
          $ref: '#/components/headers/Correlation-Key'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    Unauthorized:
      description: Unauthorized - The client must authenticate itself to get the requested response.
      headers:
        API-Version:
          $ref: '#/components/headers/API-Version'
        Correlation-Key:
          $ref: '#/components/headers/Correlation-Key'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    Forbidden:
      description: Forbidden - The client does not have access rights to the content.
      headers:
        API-Version:
          $ref: '#/components/headers/API-Version'
        Correlation-Key:
          $ref: '#/components/headers/Correlation-Key'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    NotFound:
      description: Not Found - The server can not find the requested resource.
      headers:
        API-Version:
          $ref: '#/components/headers/API-Version'
        Correlation-Key:
          $ref: '#/components/headers/Correlation-Key'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    UnprocessableEntity:
      description: Unprocessable Entity - The request was well-formed but was unable to be followed due
        to semantic errors.
      headers:
        API-Version:
          $ref: '#/components/headers/API-Version'
        Correlation-Key:
          $ref: '#/components/headers/Correlation-Key'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    TooManyRequests:
      description: Too Many Requests - The user has sent too many requests in a given amount of time.
      headers:
        API-Version:
          $ref: '#/components/headers/API-Version'
        Correlation-Key:
          $ref: '#/components/headers/Correlation-Key'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    InternalServerError:
      description: Internal Server Error - The server has encountered a situation it doesn't know how
        to handle.
      headers:
        API-Version:
          $ref: '#/components/headers/API-Version'
        Correlation-Key:
          $ref: '#/components/headers/Correlation-Key'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    ServiceUnavailable:
      description: Service Unavailable - The server is not ready to handle the request.
      headers:
        API-Version:
          $ref: '#/components/headers/API-Version'
        Correlation-Key:
          $ref: '#/components/headers/Correlation-Key'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
  headers:
    API-Version:
      description: API version
      required: true
      schema:
        type: string
        examples:
        - 1.0.0
        example: 1.0.0
    Correlation-Key:
      description: Request trace ID
      required: true
      schema:
        type: string
        format: uuid
    Location:
      description: URI of created resource
      required: true
      schema:
        type: string
        format: uri
  requestBodies:
    TenantCreate:
      description: The tenant to create.
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TenantCreate'
    TenantUpdate:
      description: The tenant properties to update.
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TenantCreate'
    HostCreate:
      description: Host object that needs to be added to the store
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/HostCreate'
  securitySchemes:
    oauth2:
      type: oauth2
      description: OAuth 2.0 client credentials. Scopes vary by surface; see individual APIs (tenants,
        hosts, access controls).
      flows:
        clientCredentials:
          tokenUrl: https://auth.gradera.ai/oauth/token
          scopes:
            tenant-man:read: Read access to TenantMan host APIs
            tenant-man:write: Write access to TenantMan host APIs
            tenants:read: Read access to tenant resources
            tenants:write: Write access to tenant resources
