# Proposed contract, version 1: endpoints, errors, paging, idempotency, security and the capability of every
# operation. Resource schemas were initialized from the data model (docs/06-data) and are kept aligned with it; input
# schemas (*Input, *Request) and views are specific to this contract. Status: proposal for review, not confirmed design.
# Conventions: docs/05-interfaces/choosing-an-interface.md. Vendor extensions: x-moonitoring-audience (who calls),
# x-moonitoring-capability (the capability checked), x-moonitoring-entitlement (the entitlement feature checked),
# x-moonitoring-requirements (the requirements of 1.requisiti-raffinati.txt the operation serves).
openapi: 3.1.0
info:
  title: Access Organizations API
  version: 1.0.0
  description: Organizations (farms, cooperatives, insurers and professionals), their users, memberships, user groups, delegations, cooperative constraints,
    the global Organization roles and the nations. Organization users act inside their own Organization; staff read
    every Organization and maintain the global roles.
servers:
- url: https://access.moonitoring.com/organizations/v1
  description: Prod
- url: https://stage-access.moonitoring.com/organizations/v1
  description: Stage, through IAP
security:
- bearer: []
tags:
- name: Me
  description: The signed-in user
- name: Organizations
  description: Farms, cooperatives, insurers and professionals
- name: Members
  description: Users and their memberships
- name: Groups
  description: User groups, their members and their roles
- name: Delegations
  description: One Organization acting for another
- name: Constraints
  description: Rules a cooperative imposes on its farms
- name: Roles
  description: The global Organization roles
- name: Nations
  description: Reference list of nations
paths:
  /me:
    get:
      summary: Who am I
      operationId: getCurrentUser
      description: 'The signed-in user, the Organizations they can act as and, for the token''s active Organization,
        the farms that delegated to it (decided 2026-11-11). Every app calls it first. `memberships` are the person''s
        own, direct and through user groups, each with an `organization_summary` (id, name, type, status): the
        Organization choice after sign-in offers only these, without a token switched to each of them. A delegated
        membership is never among them: `delegated_organizations` lists the Organizations reachable through the
        delegations of the active Organization, each with its summary and the delegated role, from which a person
        acting as a delegatee picks the subject of their work. It is empty without an active Organization and for a
        Farm, which never receives a delegation.'
      tags:
      - Me
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrentUser'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '1'
      - '5'
      - 5.*.1
      - 5.*.2
    patch:
      summary: Update my profile
      operationId: updateCurrentUser
      description: 'A Person changes their own name, surname, telephone and language. The e-mail follows the verified
        e-mail of Identity Platform and is not changed here. Works for a user with no Organization.'
      tags:
      - Me
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileUpdate'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrentUser'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - 1.*.1
      - 1.*.1.6
  /organizations:
    get:
      summary: List Organizations
      operationId: listOrganizations
      tags:
      - Organizations
      parameters:
      - name: type
        in: query
        required: false
        schema:
          type: string
          enum:
          - Farm
          - Cooperative
          - Insurer
          - Professional
        description: Only Organizations of this type.
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - pending
          - active
          - suspended
          - closing
          - closed
        description: Only this status; pending is the approval queue.
      - name: name
        in: query
        required: false
        schema:
          type: string
        description: Part of the name, case-insensitive.
      - name: nation
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Only Organizations whose fiscal identifier is of this nation.
      - name: cooperative
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Only farms of this cooperative.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Organization'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.organizations.read
      x-moonitoring-requirements:
      - '2'
      - '1006.19'
    post:
      summary: Create an Organization
      operationId: createOrganization
      description: 'Self-service onboarding (D8): any signed-in person creates an Organization of one of the four
        types, a farm, a cooperative, an insurer or a professional (decided 2026-11-11), and becomes its owner, with the Owner role as its first direct membership. The Organization is `pending` until a staff
        member approves it; until then its members can sign in and nothing else. Publishes `organization.created.v1`
        at approval.'
      tags:
      - Organizations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '2'
      - '2.5'
      - 2.*.1
      - 2.*.2
      - '5'
  /organizations/counts:
    get:
      summary: Count Organizations
      operationId: countOrganizations
      description: Decided on 2026-11-11. How many Organizations there are, in total, by status and by type, for the
        Console's basic numbers; closed ones count only under their status.
      tags:
      - Organizations
      responses:
        '200':
          description: The counts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationCounts'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.organizations.read
      x-moonitoring-requirements:
      - '2'
      - '1006.19'
  /organizations/{organization_id}:
    get:
      summary: Read an Organization
      operationId: getOrganization
      description: Members read their own Organization; staff read any with `access.organizations.read`.
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - null
      - access.organizations.read
      x-moonitoring-requirements:
      - '2'
    patch:
      summary: Update an Organization
      operationId: updateOrganization
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationUpdate'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization.update
      x-moonitoring-requirements:
      - '2'
      - '1002.7'
  /organizations/{organization_id}/closure:
    get:
      summary: Get the closure of an Organization
      operationId: getOrganizationClosure
      description: The closure in progress or the last one, with when it will run and whether it can still be cancelled.
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationClosure'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.organizations.read
      - access.organization.close
      x-moonitoring-requirements:
      - '138'
      - '2.7'
    post:
      summary: Close an Organization
      operationId: requestOrganizationClosure
      description: 'Starts the grace period of 30 days: the Organization is frozen, its members can still read and export its data, and the closure runs when the period ends. The owner''s token must carry an auth_time at most five minutes old, otherwise 403 reauthentication-required; staff close with a message the Organization is told.'
      tags:
      - Organizations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationClosureInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationClosure'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.organization.close
      - access.organizations.close
      x-moonitoring-requirements:
      - '138'
      - '138.3'
      - '2.7'
      - '1002.33'
      - '1006.43'
  /organizations/{organization_id}/closure/cancel:
    post:
      summary: Cancel a closure
      operationId: cancelOrganizationClosure
      description: Restores the Organization to the status it had before; only during the grace period. A staff decision can be cancelled only by staff.
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationClosure'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.organization.close
      - access.organizations.close
      x-moonitoring-requirements:
      - '138.9'
      - '138.10'
      - '1002.33'
      - '1006.43'
  /organizations/{organization_id}/closure/hold:
    post:
      summary: Hold a closure
      operationId: holdOrganizationClosure
      description: Postpones the closure until a date, for a dispute or a request from an authority.
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationClosureHoldInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationClosure'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.organizations.close
      x-moonitoring-requirements:
      - '138.7'
      - '138.8'
      - '1006.43'
  /organizations/{organization_id}/status:
    post:
      summary: Approve, suspend or reactivate an Organization
      operationId: setOrganizationStatus
      description: Approval of a pending Organization publishes `organization.created.v1`; a suspension publishes
        `organization.updated.v1`. Every call is a PlatformAuditEvent.
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationStatusInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.organizations.approve
      x-moonitoring-requirements:
      - '2.7'
      - '1006.38'
      - '70'
  /organizations/{organization_id}/cooperative-link-requests:
    get:
      summary: List cooperative link requests
      operationId: listCooperativeLinkRequests
      description: On a farm, the requests it made; on a cooperative, the requests it received.
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - pending
          - accepted
          - rejected
          - withdrawn
        description: Only this status.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/CooperativeLinkRequest'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: organization
      x-moonitoring-capability:
      - access.cooperative_links.manage
      - access.members.read
      x-moonitoring-requirements:
      - 2.*.2.1
    post:
      summary: Ask to join a cooperative
      operationId: requestCooperativeLink
      description: By a farm. One pending request at a time; a farm that already has a cooperative must leave it
        first.
      tags:
      - Organizations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CooperativeLinkRequestInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CooperativeLinkRequest'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_links.manage
      x-moonitoring-requirements:
      - 2.*.2.1
      - '1002.7'
  /cooperative-link-requests/{request_id}/accept:
    post:
      summary: Accept a farm into the cooperative
      operationId: acceptCooperativeLink
      description: By the cooperative. Sets the farm's `cooperative` and publishes `organization.updated.v1` for
        the farm.
      tags:
      - Organizations
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CooperativeLinkRequest'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_links.manage
      x-moonitoring-requirements:
      - 2.*.2.1
      - '1002.7'
  /cooperative-link-requests/{request_id}/reject:
    post:
      summary: Reject or withdraw a link request
      operationId: rejectCooperativeLink
      description: The cooperative rejects, or the farm withdraws its own request.
      tags:
      - Organizations
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CooperativeLinkRequest'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_links.manage
      x-moonitoring-requirements:
      - 2.*.2.1
      - '1002.7'
  /organizations/{organization_id}/cooperative/leave:
    post:
      summary: End the cooperative link
      operationId: leaveCooperative
      description: 'Either side: called on the farm it clears its cooperative; called on the cooperative with `farm`
        in the body it removes that farm. Delegations between the two are not touched.'
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                farm:
                  type: string
                  format: uuid
                  description: Only when called on the cooperative.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_links.manage
      x-moonitoring-requirements:
      - 2.*.2.1
      - '1002.7'
  /organizations/{organization_id}/member-farms:
    get:
      summary: List the member farms of a cooperative
      operationId: listCooperativeMemberFarms
      description: 'Proposed on 2026-11-10 with the predefined roles; its capability is in the catalog since
        2026-11-11, held by the predefined Owner and Manager of a cooperative. The membership data every farm linked to a
        cooperative shares with it without a delegation (confirmed 2026-10-31): name, owner contact, member since,
        link status, number of animals, when data last arrived and whether the farm meets the cooperative''s
        constraints. Nothing else of a farm is shown here; animals and records need a delegation. Open points: the
        data model has no address for an Organization, and the number of animals and the last data belong to farm,
        so how access holds them (from farm''s events, or a call) is not decided. Answers 404 when the Organization
        is not a cooperative.'
      tags:
      - Organizations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The cooperative.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MemberFarmView'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_members.read
      x-moonitoring-requirements:
      - 2.*.2.1
      - '9'
      - '1002.37'
  /organizations/{organization_id}/transfer-ownership:
    post:
      summary: Transfer the ownership
      operationId: transferOrganizationOwnership
      description: Only the current owner may call it. The new owner receives the Owner role; the previous owner
        keeps a membership with the Manager role.
      tags:
      - Organizations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OwnershipTransferRequest'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization.update
      x-moonitoring-requirements:
      - '2.5'
  /organizations/{organization_id}/members:
    get:
      summary: List members
      operationId: listMembers
      description: Direct and delegated memberships of the Organization, with their users and roles. Revoked memberships
        are included only with `include_revoked`.
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: include_revoked
        in: query
        required: false
        schema:
          type: boolean
        description: Also return memberships that ended.
      - name: user
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Only memberships of this user.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MembershipView'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.members.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '5'
      - 5.*.1
      - 5.*.2
      - '1002.8'
  /organizations/{organization_id}/invitations:
    get:
      summary: List invitations
      operationId: listInvitations
      description: 'The invitations of the Organization, pending ones first.'
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - pending
          - accepted
          - revoked
          - expired
        description: Only invitations in this status.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationInvitation'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.members.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '139'
      - '1002.8'
    post:
      summary: Invite a person
      operationId: inviteMember
      description: 'Sends an invitation to an e-mail address with a role and, optionally, groups. Nobody becomes a member until they accept; a person who is already a member is refused with 409.'
      tags:
      - Members
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvitationInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationInvitation'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '139'
      - '139.4'
      - '139.5'
      - '6.4'
      - '1002.9'
  /organizations/{organization_id}/invitations/{invitation_id}/resend:
    post:
      summary: Resend an invitation
      operationId: resendInvitation
      description: 'Sends a new link with a new expiry of seven days; the old link stops working.'
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: invitation_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The invitation.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationInvitation'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '139.7'
      - '139.8'
      - '1002.9'
  /organizations/{organization_id}/invitations/{invitation_id}/revoke:
    post:
      summary: Revoke an invitation
      operationId: revokeInvitation
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: invitation_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The invitation.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationInvitation'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '139.12'
      - '139.13'
      - '1002.9'
  /invitations/preview:
    post:
      summary: Preview an invitation
      operationId: previewInvitation
      description: 'What the link offers, before signing in: the Organization, the role, who invited and until when. The token travels in the body, never in the URL.'
      tags:
      - Members
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvitationTokenInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvitationPreview'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '139'
      - '139.8'
  /invitations/accept:
    post:
      summary: Accept an invitation
      operationId: acceptInvitation
      description: 'Called by the signed-in person whose verified e-mail is the invited one; creates their direct membership and group memberships in one write.'
      tags:
      - Members
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvitationTokenInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MembershipView'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '139.9'
      - '139.10'
      - '139.11'
      - '5.*.1'
      - '133'
  /organizations/{organization_id}/join-links:
    get:
      summary: List join links
      operationId: listJoinLinks
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationJoinLink'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.members.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '142'
      - '1002.8'
    post:
      summary: Create a join link
      operationId: createJoinLink
      description: 'A link people use to join by themselves, with a role, optional groups, an expiry of at most 30 days, optional limits on uses and e-mail domain, and an optional approval. The link is returned once and never again.'
      tags:
      - Members
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JoinLinkInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JoinLinkCreated'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '142'
      - '142.3'
      - '142.7'
      - '142.8'
      - '142.10'
      - '142.11'
      - '6.4'
      - '1002.9'
  /organizations/{organization_id}/join-links/{link_id}/revoke:
    post:
      summary: Revoke a join link
      operationId: revokeJoinLink
      description: 'The link stops working at once; people who already joined stay members.'
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: link_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The join link.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationJoinLink'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '142.12'
      - '142.13'
      - '1002.9'
  /organizations/{organization_id}/join-requests:
    get:
      summary: List join requests
      operationId: listJoinRequests
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationJoinRequest'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.members.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '143'
      - '1002.8'
  /organizations/{organization_id}/join-requests/{request_id}/approve:
    post:
      summary: Approve a join request
      operationId: approveJoinRequest
      description: 'Creates the membership with the role and groups of the link, checked against the approver''s role.'
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The join request.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationJoinRequest'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '143.4'
      - '143.5'
      - '143.6'
      - '6.4'
      - '1002.9'
  /organizations/{organization_id}/join-requests/{request_id}/reject:
    post:
      summary: Reject a join request
      operationId: rejectJoinRequest
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The join request.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationJoinRequest'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '143.4'
      - '143.5'
      - '143.6'
      - '1002.9'
  /join-links/preview:
    post:
      summary: Preview a join link
      operationId: previewJoinLink
      description: 'What the link offers before signing in: the Organization, the role and whether an approval is needed. The token travels in the body.'
      tags:
      - Members
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvitationTokenInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JoinLinkPreview'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '142'
  /join-links/join:
    post:
      summary: Join through a link
      operationId: joinThroughLink
      description: 'Called by a signed-in Person, after registering if they are new. Without an approval the membership exists at once; with one, a pending join request is returned.'
      tags:
      - Members
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvitationTokenInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JoinResult'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '142'
      - '142.9'
      - '143'
      - '5.*.1'
      - '133'
  /organizations/{organization_id}/members/{membership_id}/revoke:
    post:
      summary: Revoke a membership
      operationId: revokeMembership
      description: The membership ends now; the row is kept. Revoking a direct membership also revokes the delegated
        memberships the user holds through this Organization as delegatee.
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: membership_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationAccessControlMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '5.4'
      - '5.5'
      - '1002.9'
  /organizations/{organization_id}/members/{membership_id}/role:
    post:
      summary: Change a member's role
      operationId: changeMemberRole
      description: 'Proposed on 2026-11-10 with the predefined roles. Gives a member another role: the direct membership
        ends and a new one with the new role starts in the same transaction, so the history keeps both and nothing
        cascades. The caller must be allowed to revoke the old role and to give the new one (req 6.4: they outrank
        both and hold every capability of both), must not be the member, and must hold no role the member holds.
        Owner and Sync Client are never given or taken this way: ownership moves only by a transfer. Answers 403
        reauthentication-required when the sign-in is older than five minutes, as every write under an admin
        capability does.'
      tags:
      - Members
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: membership_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The active direct membership whose role changes.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MemberRoleChange'
      responses:
        '200':
          description: The new membership.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - 5.*.1.2
      - '6.4'
      - '1002.9'
  /organizations/{organization_id}/service-accounts:
    get:
      summary: List service accounts
      operationId: listServiceAccounts
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ServiceAccount'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.members.read
      - access.organizations.read
      x-moonitoring-requirements:
      - 1.*.2
      - '1002.8'
    post:
      summary: Create a service account
      operationId: createServiceAccount
      tags:
      - Members
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServiceAccountInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceAccountCreated'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - 1.*.2
      - 5.*.1
      - '1002.9'
  /organizations/{organization_id}/service-accounts/{user_id}/disable:
    post:
      summary: Disable a service account
      operationId: disableServiceAccount
      description: Its tokens stop being issued at once; its memberships are revoked.
      tags:
      - Members
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceAccount'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - '1.6'
      - 1.*.2
      - '1002.9'
  /organizations/{organization_id}/service-accounts/{user_id}/rotate-credential:
    post:
      summary: Rotate a service account credential
      operationId: rotateServiceAccountCredential
      description: Registers a new public key or issues a new client secret. The previous credential stays valid
        for the overlap given, then is refused.
      tags:
      - Members
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                public_key:
                  type: object
                  properties:
                    kty:
                      type: string
                    crv:
                      type: string
                    x:
                      type: string
                    kid:
                      type: string
                  required:
                  - kty
                overlap_seconds:
                  type: integer
                  description: How long both credentials are accepted.
                  minimum: 0
                  maximum: 86400
                  default: 3600
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceAccountCreated'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - 1.*.2.4
  /organizations/{organization_id}/delegations:
    get:
      summary: List delegations
      operationId: listDelegations
      description: Delegations given by this Organization and delegations it received, each with the name, type and
        status of both Organizations and the name of the Person who created it (decided 2026-11-11), so either side
        reads who the other is without being its member.
      tags:
      - Delegations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: direction
        in: query
        required: false
        schema:
          type: string
          enum:
          - given
          - received
        description: Only delegations where this Organization is the delegator (given) or the delegatee (received).
      - name: include_revoked
        in: query
        required: false
        schema:
          type: boolean
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationDelegationMembership'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.members.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '8'
      - '1002.8'
    post:
      summary: Delegate a role to another Organization
      operationId: createDelegation
      description: 'Shares the Organization with another one (decided 2026-11-11). There is no directory or search of
        Organizations: the delegatee is either the farm''s own cooperative, named by its id, or the Organization of a
        share code it created, which the caller types in; any other `delegatee` answers 422. A share code is used up by
        the delegation it makes. An unknown, used, revoked or expired code answers 404, and after ten wrong codes in an
        hour the Organization gets 429 for the rest of that hour. Only a Farm delegates, and only to a Cooperative, an
        Insurer or a Professional (decided 2026-11-11); any other pair answers 422. The role must be one the
        delegatee''s type receives (`delegatee_types`: Technician, Veterinarian or Advisor for a Cooperative or a
        Professional, Analyst for an Insurer), otherwise 422, with no admin capability, and one the caller outranks and
        whose capabilities they hold (req 6.4).
        Records the caller as `created_by`. Answers 403 reauthentication-required when the sign-in is older than five
        minutes, as every write under an admin capability does.'
      tags:
      - Delegations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DelegationInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationDelegationMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
        '429':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/TooManyRequests
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization_delegations.manage
      x-moonitoring-requirements:
      - '8'
      - '8.3'
      - '8.8'
      - '6.4'
      - '1002.6'
  /organizations/{organization_id}/delegations/{delegation_id}/revoke:
    post:
      summary: Revoke a delegation
      operationId: revokeDelegation
      description: Either side can end it, the delegator by revoking and the delegatee by renouncing, each with
        access.organization_delegations.manage in its own Organization. Also revokes every delegated membership and
        delegated group role that depends on it.
      tags:
      - Delegations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: delegation_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationDelegationMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization_delegations.manage
      x-moonitoring-requirements:
      - '8.5'
      - '8.6'
      - '1002.6'
  /organizations/{organization_id}/delegations/{delegation_id}/role:
    post:
      summary: Change the role of a delegation
      operationId: changeDelegationRole
      description: 'Decided on 2026-11-11. Called on the delegator, which alone chooses the role: the delegation keeps
        its id and its delegated memberships and delegated group roles, which take the new role in the same
        transaction, and the previous image stays in the history. It is one operation, never a revoke and a new
        delegation. The rules are those of giving it: the new role holds no admin capability, is neither Owner
        nor Sync Client and is one the delegatee''s type receives (`delegatee_types`), otherwise 422, and the caller must be allowed to give the new role and
        to revoke the old one (req 6.4: they outrank both and hold every capability of both). Answers 409 when another
        active delegation already gives the delegatee that role, and 403 reauthentication-required when the sign-in is
        older than five minutes. `access` publishes `delegation.granted.v1` again with the new role, and
        `membership.granted.v1` with it for every membership that depends on the delegation; consumers keep the latest
        by id.'
      tags:
      - Delegations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: delegation_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The active delegation this Organization gave.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DelegationRoleChange'
      responses:
        '200':
          description: The delegation with its new role.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationDelegationMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization_delegations.manage
      x-moonitoring-requirements:
      - '8.3'
      - '6.4'
      - '1002.6'
  /organizations/{organization_id}/share-codes:
    get:
      summary: List share codes
      operationId: listShareCodes
      description: The share codes that name this Organization and still work, newest first; the code itself is
        never shown again. A read, so it never asks for a sign-in at most five minutes old (decided 2026-11-11).
      tags:
      - Delegations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ShareCode'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization_delegations.manage
      x-moonitoring-requirements:
      - '8'
      - '1002.6'
    post:
      summary: Create a share code
      operationId: createShareCode
      description: 'Decided on 2026-11-11. A code that names this Organization, so a farm can share its data with it
        without any directory: an insurer, a veterinary practice or an advisor creates it and gives it to the farm, which types it
        in its share dialog (`createDelegation`). It gives nothing by itself; the farm chooses the role. Eight
        characters of Crockford Base32 shown as two groups of four, such as K7QM-4XPD, returned once and never again;
        it lasts seven days and works once. The Organization must be active, and a Cooperative, an Insurer or a
        Professional: a Farm never receives a delegation and answers 422 (decided 2026-11-11). Answers 403
        reauthentication-required when the sign-in is older than five minutes.'
      tags:
      - Delegations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      responses:
        '201':
          description: The code, shown once.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShareCodeCreated'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
        '429':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/TooManyRequests
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization_delegations.manage
      x-moonitoring-requirements:
      - '8'
      - '1002.6'
  /organizations/{organization_id}/share-codes/{share_code_id}/revoke:
    post:
      summary: Revoke a share code
      operationId: revokeShareCode
      description: The code stops working at once; a delegation already made with it stays.
      tags:
      - Delegations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: share_code_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The share code.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShareCode'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization_delegations.manage
      x-moonitoring-requirements:
      - '8'
      - '1002.6'
  /organizations/{organization_id}/share-codes/preview:
    post:
      summary: Preview a share code
      operationId: previewShareCode
      description: 'Called on the Organization that shares, before `createDelegation`, so the person sees whose code it
        is: answers the name, type and status of the Organization the code names. The code travels in the body. An
        unknown, used, revoked or expired code answers 404, the same for each, and after ten wrong codes in an hour
        the Organization gets 429 for the rest of that hour; a code of the caller''s own Organization answers 422.
        A read, so it never asks for a sign-in at most five minutes old (decided 2026-11-11).'
      tags:
      - Delegations
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ShareCodeInput'
      responses:
        '200':
          description: The Organization the code names.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationSummary'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
        '429':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/TooManyRequests
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.organization_delegations.manage
      x-moonitoring-requirements:
      - '8'
      - '1002.6'
  /organizations/{organization_id}/delegations/{delegation_id}/members:
    post:
      summary: Assign a delegated membership
      operationId: addDelegatedMember
      description: 'Called on the delegatee: gives one of its direct members the delegated role in the delegator.'
      tags:
      - Delegations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: delegation_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DelegatedMemberRequest'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MembershipView'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.members.manage
      x-moonitoring-requirements:
      - 5.*.2
      - '8'
      - '1002.9'
  /organizations/{organization_id}/groups:
    get:
      summary: List user groups
      operationId: listUserGroups
      description: The user groups of the Organization. Archived groups are included only with `include_revoked`.
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: include_revoked
        in: query
        required: false
        schema:
          type: boolean
        description: Also return the ones that ended.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/UserGroup'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.groups.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '132'
      - '1002.31'
    post:
      summary: Create a user group
      operationId: createUserGroup
      description: Creates an empty group; members and roles are added afterwards.
      tags:
      - Groups
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserGroupInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroup'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.groups.manage
      x-moonitoring-requirements:
      - '132'
      - '1002.32'
  /organizations/{organization_id}/groups/{group_id}:
    get:
      summary: Get a user group
      operationId: getUserGroup
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroup'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.groups.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '132'
      - '1002.31'
    patch:
      summary: Rename or describe a user group
      operationId: updateUserGroup
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserGroupUpdate'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroup'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.groups.manage
      x-moonitoring-requirements:
      - '132.3'
      - '132.4'
      - '1002.32'
  /organizations/{organization_id}/groups/{group_id}/archive:
    post:
      summary: Archive a user group
      operationId: archiveUserGroup
      description: The group ends now, together with every membership and every role it holds; the rows are kept.
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroup'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.groups.manage
      x-moonitoring-requirements:
      - '132.6'
      - '132.7'
      - '1002.32'
  /organizations/{organization_id}/groups/{group_id}/members:
    get:
      summary: List group members
      operationId: listUserGroupMembers
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      - name: include_revoked
        in: query
        required: false
        schema:
          type: boolean
        description: Also return the ones that ended.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/UserGroupMembership'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.groups.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '133'
      - '1002.31'
    post:
      summary: Add a group member
      operationId: addUserGroupMember
      description: The user must be a member of the Organization; the caller must be able to give the user every role the group holds.
      tags:
      - Groups
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserGroupMemberInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroupMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.groups.manage
      x-moonitoring-requirements:
      - '133'
      - '133.3'
      - '133.4'
      - '6.4'
      - '1002.32'
  /organizations/{organization_id}/groups/{group_id}/members/{group_membership_id}/revoke:
    post:
      summary: Remove a group member
      operationId: revokeUserGroupMembership
      description: The user leaves the group now and loses the roles it gave them; the row is kept.
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      - name: group_membership_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroupMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.groups.manage
      x-moonitoring-requirements:
      - '133.5'
      - '133.6'
      - '1002.32'
  /organizations/{organization_id}/groups/{group_id}/roles:
    get:
      summary: List group roles
      operationId: listUserGroupRoles
      description: The roles the group holds, in its own Organization and through delegations.
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      - name: include_revoked
        in: query
        required: false
        schema:
          type: boolean
        description: Also return the ones that ended.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/UserGroupRoleAssignment'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - access.groups.read
      - access.organizations.read
      x-moonitoring-requirements:
      - '134'
      - '1002.31'
    post:
      summary: Give a role to a group
      operationId: assignUserGroupRole
      description: Either a role of the group's Organization, or a delegation whose delegatee is the group's Organization. The caller may give only roles whose priority is lower than their own.
      tags:
      - Groups
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserGroupRoleInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroupRoleAssignment'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.groups.manage
      x-moonitoring-requirements:
      - '134'
      - '134.*.1'
      - '134.*.2'
      - '6.4'
      - '1002.32'
  /organizations/{organization_id}/groups/{group_id}/roles/{assignment_id}/revoke:
    post:
      summary: Revoke a group role
      operationId: revokeUserGroupRole
      description: Every member loses the role now; the row is kept.
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The user group.
      - name: assignment_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroupRoleAssignment'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.groups.manage
      x-moonitoring-requirements:
      - '134.4'
      - '134.5'
      - '1002.32'
  /organizations/{organization_id}/constraints:
    get:
      summary: List cooperative constraints
      operationId: listCooperativeConstraints
      description: In a cooperative, its own constraints; in a farm, those its cooperative imposes on it.
      tags:
      - Constraints
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/CooperativeConstraint'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_constraints.read
      x-moonitoring-requirements:
      - '9'
      - '1002.18'
    post:
      summary: Create a cooperative constraint
      operationId: createCooperativeConstraint
      tags:
      - Constraints
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CooperativeConstraintInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CooperativeConstraint'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_constraints.manage
      x-moonitoring-requirements:
      - '9'
      - '1002.19'
  /organizations/{organization_id}/constraints/{constraint_id}:
    patch:
      summary: Update a cooperative constraint
      operationId: updateCooperativeConstraint
      tags:
      - Constraints
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: constraint_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CooperativeConstraintInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CooperativeConstraint'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_constraints.manage
      x-moonitoring-requirements:
      - '9'
      - '1002.19'
    delete:
      summary: Delete a cooperative constraint
      operationId: deleteCooperativeConstraint
      tags:
      - Constraints
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Organization.
      - name: constraint_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '204':
          description: Done.
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: access.cooperative_constraints.manage
      x-moonitoring-requirements:
      - '9'
      - '1002.19'
  /roles:
    get:
      summary: List the Organization roles
      operationId: listOrganizationRoles
      description: 'The global roles, with their capabilities and priority. Any signed-in caller may read them:
        a member must know which roles they can assign.'
      tags:
      - Roles
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationRoleAccessControl'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '6'
    post:
      summary: Create an Organization role
      operationId: createOrganizationRole
      tags:
      - Roles
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationRoleInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationRoleAccessControl'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.organization_roles.manage
      x-moonitoring-requirements:
      - '6'
      - '1002'
      - '1006.4'
  /roles/{role_id}:
    get:
      summary: Read an Organization role
      operationId: getOrganizationRole
      tags:
      - Roles
      parameters:
      - name: role_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationRoleAccessControl'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '6'
    patch:
      summary: Update an Organization role
      operationId: updateOrganizationRole
      description: A change of capabilities reaches every Organization at once and keeps the previous image. Owner
        and Sync Client are system roles and answer 409; a predefined role keeps its key.
      tags:
      - Roles
      parameters:
      - name: role_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationRoleInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationRoleAccessControl'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.organization_roles.manage
      x-moonitoring-requirements:
      - '6'
      - '6.5'
      - '1006.4'
  /nations:
    get:
      summary: List nations
      operationId: listNations
      description: Public reference data with no personal data, so a person who is registering, and has no token yet,
        can choose the nation of their telephone (decided 2026-11-10).
      tags:
      - Nations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Nation'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '429':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/TooManyRequests
      security: []
      x-moonitoring-audience: public
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '3'
    post:
      summary: Create a nation
      operationId: createNation
      tags:
      - Nations
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NationInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Nation'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.nations.manage
      x-moonitoring-requirements:
      - '3'
      - '1006.39'
  /nations/{nation_id}:
    patch:
      summary: Update a nation
      operationId: updateNation
      tags:
      - Nations
      parameters:
      - name: nation_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NationInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Nation'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.nations.manage
      x-moonitoring-requirements:
      - '3'
      - '1006.39'
components:
  schemas:
    OrganizationCounts:
      type: object
      description: How many Organizations there are (decided 2026-11-11). `total` and `by_type` leave closed
        Organizations out, since a closed one is a tombstone; `by_status` counts every status, closed included.
      properties:
        total:
          type: integer
          description: Organizations that are not closed.
        by_status:
          type: object
          properties:
            pending:
              type: integer
            active:
              type: integer
            suspended:
              type: integer
            closing:
              type: integer
            closed:
              type: integer
          required:
          - pending
          - active
          - suspended
          - closing
          - closed
        by_type:
          type: object
          description: Organizations that are not closed, by type.
          properties:
            Farm:
              type: integer
            Cooperative:
              type: integer
            Insurer:
              type: integer
            Professional:
              type: integer
          required:
          - Farm
          - Cooperative
          - Insurer
          - Professional
      required:
      - total
      - by_status
      - by_type
    User:
      description: 'A User is anyone who acts inside an Organization: a person or a service account, a program that
        calls our API on the Organization''s behalf. Both receive roles in the same way, through memberships, and
        every change they make to data is recorded under their name in a write commit. They are separate from Moonitoring
        users, who run the platform itself.'
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        disabled_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        type:
          type: string
          enum:
          - Person
          - ServiceAccount
          description: Which kind of User this is (enum, disjoint + complete).
      required:
      - id
      - created_at
      - updated_at
      - type
    Person:
      allOf:
      - $ref: '#/components/schemas/User'
      - type: object
        properties:
          name:
            type: string
          surname:
            type: string
          email:
            type: string
            format: regex
            description: Unique.
          telephone_number:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Telephone
        required:
        - name
        - surname
        - email
        - telephone_number
      description: A User whose type is Person.
    ServiceAccount:
      allOf:
      - $ref: '#/components/schemas/User'
      - type: object
        properties:
          organization:
            type: string
            format: uuid
            description: ID of the Organization. It belongs to one Organization and can hold roles only there (DirectMembership);
              it is never delegated.
          description:
            type: string
          owner:
            type: string
            format: uuid
            description: ID of the User that is a Person. The person responsible for it.
          credential_ref:
            type: string
            description: Reference to the credential in the secret manager. Secrets and keys never enter the database.
          last_used_at:
            type: string
            format: date-time
        required:
        - organization
        - description
        - owner
        - credential_ref
      description: A User whose type is ServiceAccount.
    Organization:
      description: 'An Organization is a customer body that uses Moonitoring, always exactly one of four types: a farm
        that keeps animals, a cooperative that groups farms, an insurer that covers them, or a professional, such as a
        veterinary practice, an advisor or a laboratory, that farms share data with. It holds members, roles and data feeds, and it is the boundary of access: users see animals
        and records through the Organizations they belong to. A farm also carries the timezone used to read local
        times that sources send without an offset.'
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        name:
          type: string
        fiscal_national_identifier:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/NationalIdentifierType
          description: Unique. Regex depends on the Organization's nation.
        telephone_number:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Telephone
          description: Unique.
        owner:
          type: string
          format: uuid
          description: ID of the User that is a Person.
        members:
          type: array
          items:
            type: string
            format: uuid
          description: ID of the OrganizationAccessControlMembership that is a DirectMembership.
        status:
          type: string
          enum:
          - pending
          - active
          - suspended
          - closing
          - closed
          default: pending
          description: 'pending: created by its owner and waiting for a staff approval; its members can sign in
            but do nothing else until it is active. suspended: by staff. The event organization.created.v1 is published
            when it becomes active.'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        type:
          type: string
          enum:
          - Cooperative
          - Farm
          - Insurer
          - Professional
          description: Which type of Organization this is (enum, disjoint + complete), chosen at creation; no operation
            changes it.
      required:
      - id
      - name
      - fiscal_national_identifier
      - telephone_number
      - owner
      - created_at
      - updated_at
      - status
      - type
    Cooperative:
      allOf:
      - $ref: '#/components/schemas/Organization'
      description: A Organization whose type is Cooperative.
    Farm:
      allOf:
      - $ref: '#/components/schemas/Organization'
      - type: object
        properties:
          cooperative:
            type: string
            format: uuid
            description: ID of the Organization that is a Cooperative.
          cooperative_summary:
            $ref: '#/components/schemas/OrganizationSummary'
          timezone:
            type: string
            description: e.g. Europe/Rome. Sources often send local times without offset; they are converted with
              this timezone. IANA time zone name, such as Europe/Rome.
        required:
        - timezone
      description: A Organization whose type is Farm.
    Insurer:
      allOf:
      - $ref: '#/components/schemas/Organization'
      description: A Organization whose type is Insurer.
    Professional:
      allOf:
      - $ref: '#/components/schemas/Organization'
      description: A Organization whose type is Professional.
    Nation:
      description: Reference list of nations. A nation qualifies telephone numbers, fiscal identifiers and national
        animal identifiers, whose formats depend on the issuing country.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        name:
          type: string
          description: Unique.
        code:
          type: string
          description: Unique.
        telephone_prefix:
          type: string
      required:
      - id
      - name
      - code
      - telephone_prefix
    OrganizationAccessControlMembership:
      description: 'Grants a user a role inside an Organization. A direct membership gives a user a role in the
        Organization they belong to; a delegated membership lets a member of another Organization act through a
        delegation. Memberships are the single place to check what a user can do, and where. They are never deleted:
        a membership that ends is revoked, so the question can also be answered for any date in the past.'
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        user:
          type: string
          format: uuid
          description: ID of the User.
        assigner:
          type: string
          format: uuid
          description: ID of the User. Empty for the first member of an Organization. A ServiceAccount user can
            only have a DirectMembership in its own Organization.
        revoked_at:
          type: string
          format: date-time
          description: 'When the membership ended. Rows are never deleted: who could act where, and when, stays
            answerable for any past write number.'
        revoked_by:
          type: string
          format: uuid
          description: ID of the User.
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        type:
          type: string
          enum:
          - DirectMembership
          - DelegatedMembership
          description: Which kind of OrganizationAccessControlMembership this is (enum, disjoint + complete).
      required:
      - id
      - user
      - system_version
      - created_at
      - updated_at
      - type
    DirectMembership:
      allOf:
      - $ref: '#/components/schemas/OrganizationAccessControlMembership'
      - type: object
        properties:
          organization:
            type: string
            format: uuid
            description: ID of the Organization.
          role:
            type: string
            format: uuid
            description: ID of the OrganizationRoleAccessControl.
        required:
        - organization
        - role
      description: A OrganizationAccessControlMembership whose type is DirectMembership.
    DelegatedMembership:
      allOf:
      - $ref: '#/components/schemas/OrganizationAccessControlMembership'
      - type: object
        properties:
          delegation:
            type: string
            format: uuid
            description: ID of the OrganizationDelegationMembership. Organization and role are those of the delegation
              (delegator, role).
        required:
        - delegation
      description: A OrganizationAccessControlMembership whose type is DelegatedMembership.
    OrganizationRoleAccessControl:
      description: A named bundle of capabilities that can be given to the users of any Organization. Roles are
        global and maintained by Moonitoring administrators; their priority decides which roles a user may assign
        to others.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        name:
          type: string
          description: Unique.
        capabilities:
          type: array
          items:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/OrganizationRoleCapabilityEnum
        priority:
          type: integer
          description: Higher value = higher priority = higher permissions; also used for ordering. A user who can
            assign roles can assign only roles whose priority is lower than that of their own role.
        system_version:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
          description: A change of capabilities keeps the previous image, so what a role allowed at any past write
            is known.
        key:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/OrganizationPredefinedRoleEnum
          description: The stable key of a predefined role (req 1028), absent for any other role. Systems find a
            role by its key, never by its name. Set by access; no operation sets or changes it.
        organization_types:
          type: array
          items:
            type: string
            enum:
            - Farm
            - Cooperative
            - Insurer
            - Professional
          minItems: 1
          uniqueItems: true
          description: 'The types of Organization that offer the role (decided 2026-11-11): it is given directly,
            through a group, an invitation, a join link or to a service account only in an Organization of one of these
            types, otherwise 422.'
        delegatee_types:
          type: array
          items:
            type: string
            enum:
            - Cooperative
            - Insurer
            - Professional
          uniqueItems: true
          description: The types of Organization that can receive the role through a delegation, never a Farm; empty
            for Owner, Sync Client and every role with an admin capability.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - name
      - priority
      - organization_types
      - delegatee_types
      - system_version
      - created_at
      - updated_at
    OrganizationDelegationMembership:
      description: Lets one Organization act on behalf of another with a given role, for example a cooperative managing
        the data of one of its farms. The delegator chooses the role; members of the delegatee then receive delegated
        memberships limited to that role. The contract adds the summaries of both Organizations and the name of its
        creator, read with the delegation, so either side names the other without being its member (decided
        2026-11-11).
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        delegatee:
          type: string
          format: uuid
          description: ID of the Organization. Organization that can act on behalf of the delegator Organization; a
            Cooperative, an Insurer or a Professional, never a Farm (decided 2026-11-11).
        role:
          type: string
          format: uuid
          description: 'ID of the OrganizationRoleAccessControl. Must not include `access.organization_delegations.manage`:
            a delegation cannot be delegated further. Must not include `access.members.manage`, `access.groups.manage`, `access.organization.update`,
            `access.organization.close`, `farm.ownerships.transfer` or `access.cooperative_constraints.manage`: a
            delegatee cannot change who is in the delegator, its groups, its profile or its constraints, close it,
            nor move its animals away.'
        delegator:
          type: string
          format: uuid
          description: ID of the Organization. Organization that delegates some role to the delegatee Organization;
            always a Farm (decided 2026-11-11). Must be different from the delegatee. (delegator, delegatee, role) unique among active delegations.
        created_by:
          type: string
          format: uuid
          description: ID of the User who gave the delegation, with access.organization_delegations.manage in the
            delegator (decided 2026-11-11).
        delegatee_summary:
          $ref: '#/components/schemas/OrganizationSummary'
        delegator_summary:
          $ref: '#/components/schemas/OrganizationSummary'
        created_by_summary:
          $ref: '#/components/schemas/PersonName'
        revoked_at:
          type: string
          format: date-time
          description: When the delegation ended; rows are never deleted.
        revoked_by:
          type: string
          format: uuid
          description: ID of the User.
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - delegatee
      - role
      - delegator
      - created_by
      - delegatee_summary
      - delegator_summary
      - created_by_summary
      - system_version
      - created_at
      - updated_at
    CooperativeConstraint:
      description: A rule that a cooperative imposes on its farms, for example a minimum number of cows in lactation.
        It is reserved in the model; its kinds are not defined yet.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        cooperative:
          type: string
          format: uuid
          description: ID of the Organization that is a Cooperative.
        type:
          type: string
          enum: []
          description: Which kind of CooperativeConstraint this is (enum, disjoint + complete).
      required:
      - id
      - cooperative
      - type
    UserGroup:
      description: A set of users of one Organization that receives roles as a whole, like a Google Workspace group. A member holds every role of the group on top of their own memberships. Groups hold users only, never other groups; rows are never deleted.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        organization:
          type: string
          format: uuid
          description: ID of the Organization.
        name:
          type: string
          description: Unique among the active groups of the Organization, e.g. Technicians.
        description:
          type: string
        created_by:
          type: string
          format: uuid
          description: ID of the User.
        archived_at:
          type: string
          format: date-time
          description: When the group ended, together with its memberships and roles.
        archived_by:
          type: string
          format: uuid
          description: ID of the User.
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - organization
      - name
      - created_by
      - system_version
      - created_at
      - updated_at
    UserGroupInput:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
      required:
      - name
    UserGroupUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
    UserGroupMembership:
      description: Puts one user in one group for a period. The user must be a member of the group's Organization.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        group:
          type: string
          format: uuid
          description: ID of the UserGroup.
        user:
          type: string
          format: uuid
          description: ID of the User.
        assigner:
          type: string
          format: uuid
          description: ID of the User.
        revoked_at:
          type: string
          format: date-time
        revoked_by:
          type: string
          format: uuid
          description: ID of the User.
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - group
      - user
      - assigner
      - system_version
      - created_at
      - updated_at
    UserGroupMemberInput:
      type: object
      properties:
        user:
          type: string
          format: uuid
          description: ID of the User to add.
      required:
      - user
    UserGroupRoleAssignment:
      description: A role given to a group, in its own Organization (DirectGroupRole) or through a delegation whose delegatee is the group's Organization (DelegatedGroupRole).
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        group:
          type: string
          format: uuid
          description: ID of the UserGroup.
        assigner:
          type: string
          format: uuid
          description: ID of the User.
        revoked_at:
          type: string
          format: date-time
        revoked_by:
          type: string
          format: uuid
          description: ID of the User.
        type:
          type: string
          enum:
          - DirectGroupRole
          - DelegatedGroupRole
          description: Which kind of UserGroupRoleAssignment this is (enum, disjoint + complete).
        role:
          type: string
          format: uuid
          description: ID of the OrganizationRoleAccessControl; for a DelegatedGroupRole, the role of the delegation.
        delegation:
          type: string
          format: uuid
          description: ID of the OrganizationDelegationMembership, for a DelegatedGroupRole.
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - group
      - assigner
      - type
      - role
      - system_version
      - created_at
      - updated_at
    UserGroupRoleInput:
      description: Exactly one of role and delegation.
      type: object
      properties:
        role:
          type: string
          format: uuid
          description: A role of the group's Organization.
        delegation:
          type: string
          format: uuid
          description: A delegation whose delegatee is the group's Organization.
    OrganizationClosure:
      description: Closing an Organization the way cloud providers delete a project. The request starts a grace period
        of 30 days, during which the Organization is frozen but can be restored; at its end the closure runs once, in a
        fixed order, and cannot be undone.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        organization:
          type: string
          format: uuid
        reason:
          type: string
          enum:
          - owner_request
          - staff_decision
          - never_approved
        requested_by:
          type: string
          format: uuid
          description: ID of the User or MoonitoringUser who asked.
        requested_at:
          type: string
          format: date-time
        scheduled_for:
          type: string
          format: date-time
          description: When the closure runs; 30 days after the request, later while a hold is set.
        hold_until:
          type: string
          format: date-time
        hold_reason:
          type: string
        cancelled_at:
          type: string
          format: date-time
        cancelled_by:
          type: string
          format: uuid
        completed_at:
          type: string
          format: date-time
        erasure_request:
          type: string
          format: uuid
          description: ID of the ErasureRequest executed for a Farm.
        previous_status:
          type: string
          enum:
          - pending
          - active
          - suspended
          description: The status before the request; a cancellation restores it.
        message:
          type: string
          description: Why staff closed it, as told to the Organization; required for a staff decision.
      required:
      - id
      - organization
      - reason
      - requested_by
      - requested_at
      - scheduled_for
      - previous_status
    OrganizationClosureInput:
      type: object
      properties:
        reason:
          type: string
          enum:
          - owner_request
          - staff_decision
          - never_approved
          description: owner_request for the owner; staff_decision or never_approved for staff.
        message:
          type: string
          description: Why, as told to the Organization; required for a staff decision.
      required:
      - reason
    OrganizationClosureHoldInput:
      type: object
      properties:
        hold_until:
          type: string
          format: date-time
        hold_reason:
          type: string
      required:
      - hold_until
      - hold_reason
    OrganizationInvitation:
      description: How a person joins an Organization. The person accepts, signs in or signs up, and only then do their
        Person and their direct membership exist. The link expires after seven days; only the hash of its secret is stored.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        organization:
          type: string
          format: uuid
        email:
          type: string
          format: email
        role:
          type: string
          format: uuid
          description: ID of the OrganizationRoleAccessControl given on acceptance.
        groups:
          type: array
          items:
            type: string
            format: uuid
          description: IDs of the UserGroups joined on acceptance.
        invited_by:
          type: string
          format: uuid
        expires_at:
          type: string
          format: date-time
        status:
          type: string
          enum:
          - pending
          - accepted
          - revoked
          - expired
        accepted_by:
          type: string
          format: uuid
        accepted_at:
          type: string
          format: date-time
        revoked_by:
          type: string
          format: uuid
        revoked_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
      required:
      - id
      - organization
      - email
      - role
      - invited_by
      - expires_at
      - status
      - created_at
    InvitationInput:
      type: object
      properties:
        email:
          type: string
          format: email
        role:
          type: string
          format: uuid
          description: Its priority must be lower than that of the caller's role.
        groups:
          type: array
          items:
            type: string
            format: uuid
      required:
      - email
      - role
    InvitationTokenInput:
      type: object
      properties:
        token:
          type: string
          description: The secret from the invitation link.
      required:
      - token
    InvitationPreview:
      type: object
      properties:
        organization_name:
          type: string
        role_name:
          type: string
        invited_by_name:
          type: string
        expires_at:
          type: string
          format: date-time
      required:
      - organization_name
      - role_name
      - expires_at
    ProfileUpdate:
      type: object
      properties:
        name:
          type: string
        surname:
          type: string
        telephone_number:
          type: object
          description: The telephone, as a nation and the number without its prefix.
          properties:
            nation:
              type: string
              format: uuid
              description: ID of the Nation whose prefix the number uses.
            number:
              type: string
          required:
          - nation
          - number
        locale:
          type: string
          enum:
          - it
          - en
      additionalProperties: false
    OrganizationJoinLink:
      description: A link people use to join an Organization by themselves, within its limits.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        organization:
          type: string
          format: uuid
        role:
          type: string
          format: uuid
        groups:
          type: array
          items:
            type: string
            format: uuid
        created_by:
          type: string
          format: uuid
        expires_at:
          type: string
          format: date-time
        max_uses:
          type: integer
        uses:
          type: integer
        email_domain:
          type: string
        requires_approval:
          type: boolean
        revoked_at:
          type: string
          format: date-time
        revoked_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
      - id
      - organization
      - role
      - created_by
      - expires_at
      - uses
      - requires_approval
      - created_at
    JoinLinkInput:
      type: object
      properties:
        role:
          type: string
          format: uuid
          description: Its priority must be lower than the caller's; a role that manages members, groups, delegations
            or the Organization is refused.
        groups:
          type: array
          items:
            type: string
            format: uuid
        expires_at:
          type: string
          format: date-time
          description: At most 30 days ahead; seven days when absent.
        max_uses:
          type: integer
          minimum: 1
        email_domain:
          type: string
        requires_approval:
          type: boolean
          default: false
      required:
      - role
    JoinLinkCreated:
      allOf:
      - $ref: '#/components/schemas/OrganizationJoinLink'
      - type: object
        properties:
          url:
            type: string
            format: uri
            description: The link to share, shown only in this answer.
        required:
        - url
    JoinLinkPreview:
      type: object
      properties:
        organization_name:
          type: string
        role_name:
          type: string
        requires_approval:
          type: boolean
        expires_at:
          type: string
          format: date-time
      required:
      - organization_name
      - role_name
      - requires_approval
      - expires_at
    OrganizationJoinRequest:
      type: object
      description: A person waiting for an approval after using a join link.
      properties:
        id:
          type: string
          format: uuid
        link:
          type: string
          format: uuid
        person:
          type: string
          format: uuid
        status:
          type: string
          enum:
          - pending
          - approved
          - rejected
          - expired
        decided_by:
          type: string
          format: uuid
        decided_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
      required:
      - id
      - link
      - person
      - status
      - created_at
    JoinResult:
      type: object
      description: Exactly one of membership and join_request.
      properties:
        membership:
          $ref: '#/components/schemas/MembershipView'
        join_request:
          $ref: '#/components/schemas/OrganizationJoinRequest'
    MembershipView:
      type: object
      description: 'A membership as the Organization Dashboard shows it: the membership, its user and the role it
        grants, with the delegation when it is delegated and the user group when the role comes through one.'
      properties:
        id:
          type: string
          format: uuid
          description: The membership id; for a role through a user group, the same stable id as in membership.granted.v1.
        source:
          type: string
          enum:
          - DirectMembership
          - DelegatedMembership
          - DirectGroupRole
          - DelegatedGroupRole
          description: Where the role comes from.
        membership:
          $ref: '#/components/schemas/OrganizationAccessControlMembership'
        user_group:
          type: string
          format: uuid
          description: ID of the UserGroup, when the role comes through a group; membership is then absent.
        user:
          $ref: '#/components/schemas/User'
        role:
          $ref: '#/components/schemas/OrganizationRoleAccessControl'
        organization:
          type: string
          format: uuid
          description: ID of the Organization the membership gives access to.
        organization_summary:
          $ref: '#/components/schemas/OrganizationSummary'
        delegation:
          $ref: '#/components/schemas/OrganizationDelegationMembership'
      required:
      - id
      - source
      - user
      - role
      - organization
      - organization_summary
    OrganizationSummary:
      type: object
      description: 'What an app needs to name an Organization the caller is not acting in: the person''s Organizations
        in `GET /me`, before any token is switched to one of them (the Account app''s choice of an Organization, and
        the farm choice of the sync client and of the installer), and the two sides of a delegation, a farm''s
        cooperative and the Organization of a share code (decided 2026-11-11). Read with the membership, the
        delegation, the farm or the code, so it needs no capability of the Organization it names.'
      properties:
        id:
          type: string
          format: uuid
          description: ID of the Organization, the same as `organization`.
        name:
          type: string
        type:
          type: string
          enum:
          - Cooperative
          - Farm
          - Insurer
          - Professional
          description: Every Organization has one (decided 2026-11-11); it tells an app what to show.
        status:
          type: string
          enum:
          - pending
          - active
          - suspended
          - closing
          - closed
          description: An app offers to act only in an active Organization, and says why for the others.
      required:
      - id
      - name
      - type
      - status
    PersonName:
      type: object
      description: The name of a Person, shown to another Organization without their contacts (decided 2026-11-11),
        such as "Shared by Giovanni Ronchi".
      properties:
        id:
          type: string
          format: uuid
          description: ID of the User.
        name:
          type: string
        surname:
          type: string
      required:
      - id
      - name
      - surname
    CurrentUser:
      type: object
      description: The signed-in user and every Organization they can act in.
      properties:
        user:
          $ref: '#/components/schemas/User'
        active_organization:
          type: string
          format: uuid
          description: The Organization carried by the token.
        memberships:
          type: array
          items:
            $ref: '#/components/schemas/MembershipView'
          description: The person's own active memberships, direct and through user groups (`DirectMembership`,
            `DirectGroupRole`); the Organization choice after sign-in offers only these. Never a delegated one.
        delegated_organizations:
          type: array
          items:
            $ref: '#/components/schemas/DelegatedOrganizationView'
          description: The Organizations the person reaches through the delegations of the token's active Organization,
            where they hold a delegated membership or a delegated group role; empty without an active Organization.
      required:
      - user
      - memberships
      - delegated_organizations
    DelegatedOrganizationView:
      type: object
      description: 'A farm the person can work on as the subject while acting as the delegatee, the token''s active
        Organization (decided 2026-11-11). The token stays the delegatee''s: the app calls the farm''s resources with
        its id in the path, and the delegated role counts only while the delegatee is the active Organization.'
      properties:
        organization:
          type: string
          format: uuid
          description: ID of the delegator, the farm.
        organization_summary:
          $ref: '#/components/schemas/OrganizationSummary'
        role:
          $ref: '#/components/schemas/OrganizationRoleAccessControl'
        source:
          type: string
          enum:
          - DelegatedMembership
          - DelegatedGroupRole
          description: Where the person's delegated role comes from.
        delegation:
          type: string
          format: uuid
          description: ID of the OrganizationDelegationMembership.
      required:
      - organization
      - organization_summary
      - role
      - source
      - delegation
    OrganizationInput:
      type: object
      description: Input to create an Organization. `type` says whether it is a Farm, a Cooperative, an Insurer or a
        Professional, and no operation changes it later; `timezone` applies to a Farm only. The caller becomes the owner and first member; the Organization waits as pending
        for a staff approval.
      properties:
        name:
          type: string
        fiscal_national_identifier:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/NationalIdentifierType
          description: Unique. Regex depends on the Organization's nation.
        telephone_number:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Telephone
          description: Unique.
        type:
          type: string
          enum:
          - Cooperative
          - Farm
          - Insurer
          - Professional
          description: Which type of Organization this is (enum, disjoint + complete).
        timezone:
          type: string
          description: e.g. Europe/Rome. Sources often send local times without offset; they are converted with
            this timezone. IANA time zone name, such as Europe/Rome.
      required:
      - name
      - fiscal_national_identifier
      - telephone_number
      - type
      additionalProperties: false
    OrganizationUpdate:
      type: object
      description: Fields of an Organization that its members may change. `timezone` applies to a Farm only; the
        cooperative of a farm is set through a link request the cooperative accepts (D8), and the status by staff.
      properties:
        name:
          type: string
        fiscal_national_identifier:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/NationalIdentifierType
          description: Unique. Regex depends on the Organization's nation.
        telephone_number:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Telephone
          description: Unique.
        timezone:
          type: string
          description: e.g. Europe/Rome. Sources often send local times without offset; they are converted with
            this timezone. IANA time zone name, such as Europe/Rome.
      additionalProperties: false
    ServiceAccountInput:
      type: object
      description: 'Creates a service account of the Organization: a program that calls our API on the Organization''s
        behalf, such as a cooperative''s system or the farm sync client.'
      properties:
        description:
          type: string
        role:
          type: string
          format: uuid
          description: ID of the OrganizationRoleAccessControl it holds in this Organization.
        public_key:
          type: object
          description: The public key (JWK) the program will sign its token requests with (`private_key_jwt`). When
            absent, a one-time client secret is returned instead.
          properties:
            kty:
              type: string
            crv:
              type: string
            x:
              type: string
            kid:
              type: string
          required:
          - kty
      required:
      - description
      - role
    ServiceAccountCreated:
      type: object
      description: The new service account and, when no public key was given, its client secret, shown once and
        never stored.
      properties:
        service_account:
          $ref: '#/components/schemas/ServiceAccount'
        membership:
          $ref: '#/components/schemas/OrganizationAccessControlMembership'
        client_secret:
          type: string
          description: Shown once. Stored only as a hash.
      required:
      - service_account
      - membership
    DelegationInput:
      type: object
      description: Lets another Organization act on behalf of this one with a role. The role may not contain the
        capabilities that change who is in the delegator, its profile or its constraints, nor move its animals away;
        the Sync Client role is never delegated (D3), and the role must be one the delegatee's type receives
        (`delegatee_types`). Exactly one of delegatee and share_code (decided 2026-11-11).
      properties:
        delegatee:
          type: string
          format: uuid
          description: ID of the Organization that will act for this one; only a farm's own cooperative is named by
            its id.
        share_code:
          type: string
          description: The share code the other Organization gave, such as K7QM-4XPD, read without case, spaces or
            hyphens.
        role:
          type: string
          format: uuid
          description: ID of the OrganizationRoleAccessControl.
      required:
      - role
      oneOf:
      - required:
        - delegatee
      - required:
        - share_code
      additionalProperties: false
    DelegationRoleChange:
      type: object
      description: The role a delegation gives instead of its current one.
      properties:
        role:
          type: string
          format: uuid
          description: ID of the OrganizationRoleAccessControl; no admin capability, never Owner or Sync Client.
      required:
      - role
      additionalProperties: false
    ShareCode:
      type: object
      description: 'A code that names an Organization so that a farm can share with it (decided 2026-11-11). Not an
        entity of the data model: internal state of access, defined with the delegations (req 8). Its value is never
        returned after creation; access keeps a keyed hash of it.'
      properties:
        id:
          type: string
          format: uuid
        organization:
          type: string
          format: uuid
          description: ID of the Organization the code names, the future delegatee.
        created_by:
          type: string
          format: uuid
          description: ID of the User.
        expires_at:
          type: string
          format: date-time
          description: Seven days after creation.
        used_at:
          type: string
          format: date-time
        delegation:
          type: string
          format: uuid
          description: ID of the OrganizationDelegationMembership made with it; a code works once.
        revoked_at:
          type: string
          format: date-time
        revoked_by:
          type: string
          format: uuid
          description: ID of the User.
        created_at:
          type: string
          format: date-time
      required:
      - id
      - organization
      - created_by
      - expires_at
      - created_at
    ShareCodeCreated:
      type: object
      description: A new share code with its value, returned this once.
      properties:
        share_code:
          $ref: '#/components/schemas/ShareCode'
        code:
          type: string
          description: Eight characters of Crockford Base32 as two groups of four, such as K7QM-4XPD.
      required:
      - share_code
      - code
    ShareCodeInput:
      type: object
      description: A share code as the person typed it.
      properties:
        code:
          type: string
          description: Read without case, spaces or hyphens.
      required:
      - code
      additionalProperties: false
    DelegatedMemberRequest:
      type: object
      description: Gives one member of the delegatee a delegated membership under a delegation.
      properties:
        user:
          type: string
          format: uuid
          description: ID of the User; must hold a direct membership in the delegatee.
      required:
      - user
    MemberRoleChange:
      type: object
      description: The role a member gets instead of the one of the membership.
      properties:
        role:
          type: string
          format: uuid
          description: ID of the OrganizationRoleAccessControl; never Owner or Sync Client.
      required:
      - role
      additionalProperties: false
    MemberFarmView:
      type: object
      description: 'What a member farm shares with its cooperative without a delegation. Proposed on 2026-11-10.'
      properties:
        farm:
          type: string
          format: uuid
          description: ID of the Organization, a Farm.
        name:
          type: string
        owner_name:
          type: string
          description: Name and surname of the farm's owner.
        owner_telephone:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Telephone
        member_since:
          type: string
          format: date-time
          description: When the cooperative accepted the link.
        link_status:
          type: string
          enum:
          - active
          - ended
        animal_count:
          type: integer
          minimum: 0
          description: Animals the farm owns now.
        last_data_at:
          type: string
          format: date-time
          description: When data last arrived from the farm; absent when none has.
        meets_constraints:
          type: boolean
          description: Whether the farm meets every constraint of the cooperative (req 9).
      required:
      - farm
      - name
      - member_since
      - link_status
    OwnershipTransferRequest:
      type: object
      description: Moves the ownership of the Organization to another member.
      properties:
        new_owner:
          type: string
          format: uuid
          description: ID of a Person who is a direct member of the Organization.
      required:
      - new_owner
    CooperativeConstraintInput:
      type: object
      description: A constraint a cooperative imposes on its farms. Its kinds are not defined yet; `type` and `parameters`
        are reserved.
      properties:
        type:
          type: string
          enum: []
          description: Which kind of CooperativeConstraint this is (enum, disjoint + complete).
        parameters:
          type: object
          description: The parameters of the kind, once kinds are defined.
          additionalProperties: true
      required:
      - type
      additionalProperties: false
    OrganizationRoleInput:
      type: object
      description: A global Organization role. Every capability must exist in the catalog of a system; access rejects
        a name no system publishes.
      properties:
        name:
          type: string
          description: Unique.
        capabilities:
          type: array
          items:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/OrganizationRoleCapabilityEnum
        priority:
          type: integer
          description: Higher value = higher priority = higher permissions; also used for ordering. A user who can
            assign roles can assign only roles whose priority is lower than that of their own role.
        organization_types:
          type: array
          items:
            type: string
            enum:
            - Farm
            - Cooperative
            - Insurer
            - Professional
          minItems: 1
          uniqueItems: true
          description: 'The types of Organization that offer the role (decided 2026-11-11): it is given directly,
            through a group, an invitation, a join link or to a service account only in an Organization of one of these
            types, otherwise 422.'
        delegatee_types:
          type: array
          items:
            type: string
            enum:
            - Cooperative
            - Insurer
            - Professional
          uniqueItems: true
          description: The types of Organization that can receive the role through a delegation, never a Farm; empty
            for Owner, Sync Client and every role with an admin capability.
      required:
      - name
      - priority
      - organization_types
      additionalProperties: false
    NationInput:
      type: object
      description: Input to create or change a Nation; server-managed fields are left out.
      properties:
        name:
          type: string
          description: Unique.
        code:
          type: string
          description: Unique.
        telephone_prefix:
          type: string
      required:
      - name
      - code
      - telephone_prefix
      additionalProperties: false
    CooperativeLinkRequest:
      type: object
      description: 'A farm''s request to join a cooperative, transient until the cooperative decides (D8). Not an
        entity of the data model: once accepted, the link is the farm''s `cooperative` field.'
      properties:
        id:
          type: string
          format: uuid
        farm:
          type: string
          format: uuid
        cooperative:
          type: string
          format: uuid
        status:
          type: string
          enum:
          - pending
          - accepted
          - rejected
          - withdrawn
        requested_by:
          type: string
          format: uuid
          description: ID of the User.
        decided_by:
          type: string
          format: uuid
          description: ID of the User of the cooperative.
        message:
          type: string
        created_at:
          type: string
          format: date-time
        decided_at:
          type: string
          format: date-time
      required:
      - id
      - farm
      - cooperative
      - status
      - requested_by
      - created_at
    CooperativeLinkRequestInput:
      type: object
      description: Asks a cooperative to accept the farm.
      properties:
        cooperative:
          type: string
          format: uuid
        message:
          type: string
      required:
      - cooperative
    OrganizationStatusInput:
      type: object
      description: Approves a pending Organization, or suspends and reactivates one.
      properties:
        status:
          type: string
          enum:
          - active
          - suspended
        reason:
          type: string
      required:
      - status
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'The short-lived token signed by `access`: an Organization user token, a staff token or a client
        token, as the operation''s audience says.'
