# 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: Grant Calls API
  version: 1.0.0
  description: 'Funding calls for livestock farms, every fact cited from its source document (req 200 to 209). The
    public reads the published catalogue, one call at a time or by region and purpose; staff curate the register
    of sources, register research collections, launch extraction batches, publish, hold and restore revisions. Nothing
    starts work automatically: only an operator launches a batch.'
servers:
- url: https://grant.moonitoring.com/calls/v1
  description: Prod
- url: https://stage-grant.moonitoring.com/calls/v1
  description: Stage, through IAP
security:
- bearer: []
tags:
- name: Catalogue
  description: Published calls, public
- name: Calls
  description: Calls and their revisions, staff
- name: Sources
  description: The register and the collections
- name: Batches
  description: Extraction batches and provider requests
paths:
  /catalogue:
    get:
      summary: List published calls
      operationId: listPublishedCalls
      description: 'Published calls not definitely closed, with no location filter unless given: the public directory,
        one page per region and per purpose group. Results for a farm are in the Research API.'
      tags:
      - Catalogue
      parameters:
      - name: region
        in: query
        required: false
        schema:
          type: string
        description: 'ISTAT region code: calls whose search area lies in the region, then the national ones.'
      - name: purpose
        in: query
        required: false
        schema:
          type: string
        description: A purpose group (req 1206).
      - name: availability
        in: query
        required: false
        schema:
          type: string
          enum:
          - open
          - upcoming
          - to_confirm
        description: Only this availability now.
      - $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/PublishedCall'
                  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
      security:
      - {}
      - bearer: []
      x-moonitoring-audience: public
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '202'
      - '202.6'
      - '1208'
      - '1212'
      - '1206'
  /catalogue/{call_id}:
    get:
      summary: Read a published call
      operationId: getPublishedCall
      description: A closed call keeps its page for existing links. A call that is not published answers 404 to
        the public.
      tags:
      - Catalogue
      parameters:
      - name: call_id
        in: path
        required: true
        schema:
          type: string
        description: The call's public id.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublishedCall'
        '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
      security:
      - {}
      - bearer: []
      x-moonitoring-audience: public
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '202'
      - '1205'
      - '209'
  /catalogue/{call_id}/documents/{document_hash}/download-url:
    post:
      summary: Download a source document
      operationId: getSourceDocumentUrl
      description: By known hash only, never by path; a signed read URL to the original.
      tags:
      - Catalogue
      parameters:
      - name: call_id
        in: path
        required: true
        schema:
          type: string
        description: The call's public id.
      - name: document_hash
        in: path
        required: true
        schema:
          type: string
        description: SHA-256.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SignedUrl
        '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
      security:
      - {}
      - bearer: []
      x-moonitoring-audience: public
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '203'
      - '204'
  /farm-directory:
    get:
      summary: Search the farm directory
      operationId: searchFarmDirectory
      description: At least three characters, at most ten rows; picking an entry fills only the name and the comune.
      tags:
      - Catalogue
      parameters:
      - name: q
        in: query
        required: true
        schema:
          type: string
        description: Part of the name.
      - $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:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                        name:
                          type: string
                          description: Title-cased in the response.
                        municipality:
                          $ref: '#/components/schemas/Municipality'
                      required:
                      - id
                      - name
                      - municipality
                  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
      security:
      - {}
      - bearer: []
      x-moonitoring-audience: public
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '211'
  /municipalities:
    get:
      summary: Search municipalities
      operationId: searchMunicipalities
      description: At least three characters, at most ten rows.
      tags:
      - Catalogue
      parameters:
      - name: q
        in: query
        required: true
        schema:
          type: string
        description: Part of the name.
      - $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/Municipality'
                  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
      security:
      - {}
      - bearer: []
      x-moonitoring-audience: public
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '210'
  /calls:
    get:
      summary: List calls
      operationId: listCalls
      tags:
      - Calls
      parameters:
      - name: published
        in: query
        required: false
        schema:
          type: boolean
      - name: held
        in: query
        required: false
        schema:
          type: boolean
        description: Only calls with a publication hold.
      - name: farm_fit
        in: query
        required: false
        schema:
          type: string
          enum:
          - explicit
          - generic
          - excluded
          - unknown
        description: Only this fit.
      - name: q
        in: query
        required: false
        schema:
          type: string
        description: Part of the id or URL.
      - $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/FundingCall'
                  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: grant.calls.manage
      x-moonitoring-requirements:
      - '202'
      - '1006.35'
  /calls/{call_id}:
    get:
      summary: Read a call
      operationId: getCall
      tags:
      - Calls
      parameters:
      - name: call_id
        in: path
        required: true
        schema:
          type: string
        description: The call's public id.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FundingCall'
        '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: staff
      x-moonitoring-capability: grant.calls.manage
      x-moonitoring-requirements:
      - '202'
  /calls/{call_id}/documents:
    get:
      summary: List a call's documents
      operationId: listCallDocuments
      tags:
      - Calls
      parameters:
      - name: call_id
        in: path
        required: true
        schema:
          type: string
        description: The call's public id.
      - $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/CallDocument'
                  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: staff
      x-moonitoring-capability: grant.calls.manage
      x-moonitoring-requirements:
      - '204'
      - '203'
  /calls/{call_id}/revisions:
    get:
      summary: List a call's revisions
      operationId: listCallRevisions
      description: Every revision ever stored, newest first.
      tags:
      - Calls
      parameters:
      - name: call_id
        in: path
        required: true
        schema:
          type: string
        description: The call's public id.
      - $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/ExtractionRun'
                  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: staff
      x-moonitoring-capability: grant.calls.manage
      x-moonitoring-requirements:
      - '207'
      - 207.*.1
  /calls/{call_id}/territories:
    get:
      summary: List a call's territories
      operationId: listCallTerritories
      tags:
      - Calls
      parameters:
      - name: call_id
        in: path
        required: true
        schema:
          type: string
        description: The call's public id.
      - $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/CallTerritory'
                  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: staff
      x-moonitoring-capability: grant.calls.manage
      x-moonitoring-requirements:
      - '209'
      - '1202'
  /calls/{call_id}/hold:
    post:
      summary: Hold or release a call
      operationId: holdCall
      description: Bumps the catalogue version; every call is a PlatformAuditEvent.
      tags:
      - Calls
      parameters:
      - name: call_id
        in: path
        required: true
        schema:
          type: string
        description: The call's public id.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HoldRequest'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FundingCall'
        '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: grant.calls.manage
      x-moonitoring-requirements:
      - '202.8'
      - '1006.35'
      - '70'
  /calls/{call_id}/restore:
    post:
      summary: Restore an earlier revision
      operationId: restoreCallRevision
      tags:
      - Calls
      parameters:
      - name: call_id
        in: path
        required: true
        schema:
          type: string
        description: The call's public id.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RestoreRequest'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FundingCall'
        '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: grant.calls.manage
      x-moonitoring-requirements:
      - '202.5'
      - '207'
      - '1006.35'
      - '70'
  /publications:
    post:
      summary: Publish or revert a batch's revisions
      operationId: publishBatch
      description: Selects each revision when the publication rule finds no gap, projects territories and farm fit,
        bumps the catalogue version, all in one transaction per call.
      tags:
      - Calls
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishRequest'
      responses:
        '202':
          description: The result.
          content:
            application/json:
              schema:
                type: object
                description: The request was accepted; the work continues in the background and can be followed
                  by its id.
                properties:
                  id:
                    type: string
                    format: uuid
                    description: The resource or run that was created to follow the work.
                  status:
                    type: string
                required:
                - id
        '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: grant.calls.manage
      x-moonitoring-requirements:
      - '202.5'
      - '202.6'
      - '202.7'
      - '209'
      - '1006.35'
      - '70'
  /search-area-assignments:
    get:
      summary: List reviewed search areas
      operationId: listSearchAreaAssignments
      tags:
      - Calls
      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/SearchAreaAssignment'
                  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: grant.calls.manage
      x-moonitoring-requirements:
      - '208'
    post:
      summary: Add a reviewed search area
      operationId: createSearchAreaAssignment
      tags:
      - Calls
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchAreaAssignmentInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchAreaAssignment'
        '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: grant.calls.manage
      x-moonitoring-requirements:
      - '208'
      - '1006.35'
      - '70'
  /sources:
    get:
      summary: List the register of sources
      operationId: listFundingCallSources
      tags:
      - Sources
      parameters:
      - name: level
        in: query
        required: false
        schema:
          type: string
          enum:
          - european
          - italian
          - regional
          - local
        description: Only this level.
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - verified
          - needs_review
          - blocked
          - retired
        description: Only this status.
      - name: territory
        in: query
        required: false
        schema:
          type: string
      - $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/FundingCallSource'
                  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: grant.sources.manage
      x-moonitoring-requirements:
      - '200'
      - '1006.36'
    post:
      summary: Add a source
      operationId: createFundingCallSource
      tags:
      - Sources
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FundingCallSourceInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FundingCallSource'
        '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: grant.sources.manage
      x-moonitoring-requirements:
      - '200'
      - '1006.36'
      - '70'
  /sources/{source_id}:
    patch:
      summary: Update a source
      operationId: updateFundingCallSource
      tags:
      - Sources
      parameters:
      - name: source_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FundingCallSourceInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FundingCallSource'
        '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: grant.sources.manage
      x-moonitoring-requirements:
      - '200'
      - '200.12'
      - '1006.36'
      - '70'
  /collections:
    get:
      summary: List collections
      operationId: listGrantCollections
      tags:
      - Sources
      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/GrantCollection'
                  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: grant.sources.manage
      x-moonitoring-requirements:
      - '201'
    post:
      summary: Register a collection
      operationId: registerGrantCollection
      description: Validate, match, then write; with `dry_run` only the report. Nothing registered is changed; a
        repeat adds nothing.
      tags:
      - Sources
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GrantCollectionInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantCollectionReport'
        '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: grant.sources.manage
      x-moonitoring-requirements:
      - '201'
      - '202'
      - '203'
      - '204'
      - '1006.36'
      - '70'
  /collections/{collection_id}:
    get:
      summary: Read a collection
      operationId: getGrantCollection
      tags:
      - Sources
      parameters:
      - name: collection_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantCollection'
        '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: staff
      x-moonitoring-capability: grant.sources.manage
      x-moonitoring-requirements:
      - '201'
  /batches:
    get:
      summary: List batches
      operationId: listGrantBatches
      tags:
      - Batches
      parameters:
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - queued
          - running
          - done
          - failed
        description: Only this status.
      - name: active
        in: query
        required: false
        schema:
          type: boolean
        description: Only the one active batch.
      - $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/GrantBatch'
                  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: grant.sources.manage
      x-moonitoring-requirements:
      - '205'
    post:
      summary: Launch a batch
      operationId: createGrantBatch
      description: Refused while another batch is active, or over the limits. Model calls go through ai-gateway
        and are metered per the staff member.
      tags:
      - Batches
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GrantBatchInput'
      responses:
        '202':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantBatch'
        '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: grant.sources.manage
      x-moonitoring-requirements:
      - '205'
      - '206'
      - '207'
      - '1006.36'
      - '70'
  /batches/forecast:
    post:
      summary: Forecast a launch
      operationId: forecastGrantBatch
      description: Buys nothing.
      tags:
      - Batches
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GrantBatchInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchForecast'
        '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: grant.sources.manage
      x-moonitoring-requirements:
      - '205.3'
      - '205.4'
  /batches/{batch_id}:
    get:
      summary: Read a batch
      operationId: getGrantBatch
      tags:
      - Batches
      parameters:
      - name: batch_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantBatch'
        '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: staff
      x-moonitoring-capability: grant.sources.manage
      x-moonitoring-requirements:
      - '205'
  /batches/{batch_id}/resume:
    post:
      summary: Resume a batch
      operationId: resumeGrantBatch
      description: After an execution died or stopped; everything a pass bought is reused.
      tags:
      - Batches
      parameters:
      - name: batch_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '202':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantBatch'
        '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: staff
      x-moonitoring-capability: grant.sources.manage
      x-moonitoring-requirements:
      - '205.7'
      - '205.9'
      - '1006.36'
  /batches/{batch_id}/fail:
    post:
      summary: Mark a batch failed
      operationId: failGrantBatch
      description: Frees the slot for a new launch.
      tags:
      - Batches
      parameters:
      - name: batch_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantBatch'
        '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: staff
      x-moonitoring-capability: grant.sources.manage
      x-moonitoring-requirements:
      - '205.6'
      - '1006.36'
  /batches/{batch_id}/provider-requests:
    get:
      summary: List a batch's provider requests
      operationId: listProviderRequests
      tags:
      - Batches
      parameters:
      - name: batch_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: stage
        in: query
        required: false
        schema:
          type: string
          enum:
          - ocr_page
          - reading
          - card_wording
        description: Only this stage.
      - $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/ProviderRequest'
                  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: staff
      x-moonitoring-capability: grant.sources.manage
      x-moonitoring-requirements:
      - '206'
  /batches/{batch_id}/runs:
    get:
      summary: List a batch's runs
      operationId: listBatchRuns
      tags:
      - Batches
      parameters:
      - name: batch_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: kind
        in: query
        required: false
        schema:
          type: string
          enum:
          - CallRevision
          - OcrPage
        description: Only this kind.
      - $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/ExtractionRun'
                  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: staff
      x-moonitoring-capability: grant.sources.manage
      x-moonitoring-requirements:
      - '207'
  /documents/{document_hash}/text-reset:
    post:
      summary: Reset a document's text
      operationId: resetSourceDocumentText
      description: Unregisters the prepared text so the next batch prepares it again.
      tags:
      - Batches
      parameters:
      - name: document_hash
        in: path
        required: true
        schema:
          type: string
        description: SHA-256.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SourceDocument'
        '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: staff
      x-moonitoring-capability: grant.sources.manage
      x-moonitoring-requirements:
      - '203.8'
      - '1006.36'
components:
  schemas:
    Citation:
      type: object
      description: Document, page and the quote that supports a value (req 1202).
      properties:
        document:
          type: string
          description: SHA-256 of the SourceDocument.
        page:
          type: integer
        quote:
          type: string
      required:
      - document
      - page
      - quote
    FundingCallSource:
      type: object
      description: One official page to revisit when collecting calls (req 200). Research input only.
      properties:
        id:
          type: string
          format: uuid
        source_id:
          type: string
          description: Stable kebab-case identifier.
        level:
          type: string
          enum:
          - european
          - italian
          - regional
          - local
        publisher:
          type: string
        publisher_type:
          type: string
          enum:
          - ministry
          - paying_agency
          - development_agency
          - eu_body
          - directory
          - region
          - gal
          - chamber
          - municipality
          - province
          - mountain_community
          - park
          - other
        territories:
          type: array
          items:
            type: string
        url:
          type: string
          format: uri
        page_type:
          type: string
          enum:
          - calls
          - calendar
          - updates
          - bulletin
          - scheme
          - directory
        scope_notes:
          type: string
        discovered_from:
          type: string
        last_verified_at:
          type: string
          format: date
        status:
          type: string
          enum:
          - verified
          - needs_review
          - blocked
          - retired
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - source_id
      - level
      - publisher
      - publisher_type
      - url
      - page_type
      - status
      - created_at
      - updated_at
    GrantCollection:
      type: object
      description: One research run over the register, registered as calls, documents and associations (req 201).
      properties:
        id:
          type: string
          format: uuid
        window_start:
          type: string
          format: date
        window_end:
          type: string
          format: date
        sources:
          type: array
          items:
            type: string
            format: uuid
        path:
          type: string
          description: Bucket prefix of the collection folder.
        status:
          type: string
          enum:
          - validated
          - matched
          - registered
        registered_at:
          type: string
          format: date-time
        registered_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
      - id
      - window_start
      - sources
      - path
      - status
      - created_at
    FundingCall:
      type: object
      description: 'One funding call: its registered identity and the projection of its selected revision (req 202).'
      properties:
        id:
          type: string
          description: The last segment of the public page; public and stable.
        scheme_slug:
          type: string
        official_url:
          type: string
          format: uri
        archive_regions:
          type: array
          items:
            type: string
        selected_revision:
          type: string
          format: uuid
          description: ID of the CallRevision whose record is published.
        published:
          type: boolean
        missing_required:
          type: array
          items:
            type: string
        publication_hold:
          type: string
        farm_fit:
          type: string
          enum:
          - explicit
          - generic
          - excluded
          - unknown
        source_coverage:
          type: object
          additionalProperties: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - scheme_slug
      - official_url
      - archive_regions
      - published
      - farm_fit
      - created_at
      - updated_at
    VerifiedRecord:
      type: object
      description: 'The published shape answer-1 (req 1205): the checked answer with its located evidence, the card
        and the short wording. Each question is an envelope with state, reason, facts and alternatives; every fact
        carries its citations.'
      properties:
        target:
          type: string
          enum:
          - resolved
          - several_calls
          - historical_only
          - unresolved
        offer:
          type: string
          enum:
          - not_an_offer
          - upcoming
          - offer
        roles:
          type: array
          items:
            type: object
            additionalProperties: true
        agriculture_exclusion:
          type: boolean
        places:
          type: array
          items:
            type: object
            additionalProperties: true
        application_windows:
          type: array
          items:
            type: object
            additionalProperties: true
        payment_windows:
          type: array
          items:
            type: object
            additionalProperties: true
        benefits:
          type: array
          items:
            type: object
            additionalProperties: true
        budget:
          type: object
          additionalProperties: true
        aid_regime:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/CodedValue
        requirements:
          type: array
          items:
            $ref: '#/components/schemas/RequirementClause'
        details:
          type: array
          items:
            type: object
            additionalProperties: true
        card:
          type: object
          additionalProperties: true
        short:
          type: object
          additionalProperties: true
      required:
      - target
      - card
    RequirementClause:
      type: object
      description: A typed access clause; any one alternative meets it (req 1203).
      properties:
        any_of:
          type: array
          items:
            type: object
            properties:
              fact:
                type: string
                description: A FactKey (req 1200).
              operator:
                type: string
                enum:
                - eq
                - in
                - gte
                - lte
                - between
                - prefix
              values:
                type: array
                items:
                  type: string
            required:
            - fact
            - operator
            - values
        subject:
          type: string
        branch:
          type: string
        citations:
          type: array
          items:
            $ref: '#/components/schemas/Citation'
      required:
      - any_of
      - subject
      - citations
    PublishedCall:
      type: object
      description: 'A published call as the site shows it: the record, its availability now in Europe/Rome (req
        1208), its search area (req 1212) and its documents.'
      properties:
        call:
          $ref: '#/components/schemas/FundingCall'
        record:
          $ref: '#/components/schemas/VerifiedRecord'
        availability:
          type: string
          enum:
          - open
          - upcoming
          - closed
          - to_confirm
        next_deadline:
          type: string
          description: The closing of the farmer's entry round, or words when it is no date.
        search_area:
          type: object
          properties:
            kind:
              type: string
              enum:
              - assigned
              - national
              - territories
              - archive_regions
              - unrestricted
            codes:
              type: array
              items:
                type: string
          required:
          - kind
        documents:
          type: array
          items:
            $ref: '#/components/schemas/CallDocument'
      required:
      - call
      - record
      - availability
    SourceDocument:
      type: object
      description: One official document, stored once by its hash (req 203).
      properties:
        hash:
          type: string
          description: SHA-256 of the bytes.
        archive_path:
          type: string
        byte_size:
          type: integer
        content_type:
          type: string
        storage_uri:
          type: string
        text_hash:
          type: string
        text_uri:
          type: string
        text_status:
          type: string
          enum:
          - pending
          - ready
          - partial
          - failed
          - unsupported
        text_error:
          type: string
        page_count:
          type: integer
        has_ocr:
          type: boolean
        created_at:
          type: string
          format: date-time
      required:
      - hash
      - archive_path
      - byte_size
      - content_type
      - text_status
      - has_ocr
      - created_at
    CallDocument:
      type: object
      description: Which document belongs to which call (req 204).
      properties:
        id:
          type: string
          format: uuid
        call:
          type: string
        document:
          type: string
          description: SHA-256.
        role:
          type: string
          description: call, rules, amendment, annex, form, faq, other.
        original_filename:
          type: string
        source_url:
          type: string
          format: uri
      required:
      - id
      - call
      - document
      - role
      - source_url
    CallTerritory:
      type: object
      description: One coded place of a call's selected record (req 209).
      properties:
        id:
          type: string
          format: uuid
        call:
          type: string
        level:
          type: string
          enum:
          - region
          - province
          - municipality
        subject:
          type: string
          enum:
          - legal_seat
          - operating_site
          - investment_site
          - damaged_asset
          - holding
          - other
        istat_code:
          type: string
        phrase:
          type: string
        citation:
          $ref: '#/components/schemas/Citation'
      required:
      - id
      - call
      - level
      - subject
      - istat_code
      - phrase
    SearchAreaAssignment:
      type: object
      description: A reviewed geography for calls whose places the sources do not establish (req 208).
      properties:
        id:
          type: string
          format: uuid
        calls:
          type: array
          items:
            type: string
        level:
          type: string
          enum:
          - region
          - province
          - municipality
        codes:
          type: array
          items:
            type: string
        sources:
          type: array
          items:
            type: string
        note:
          type: string
        reviewed_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
      - id
      - calls
      - level
      - codes
      - sources
      - note
      - created_at
    GrantBatch:
      type: object
      description: One manual extraction launch; at most one active per database (req 205).
      properties:
        id:
          type: string
          format: uuid
        environment:
          type: string
          enum:
          - preview
          - production
        selection:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Call id to document hashes.
        reference_date:
          type: string
          format: date
        status:
          type: string
          enum:
          - queued
          - running
          - done
          - failed
        execution:
          type: string
        report_uri:
          type: string
        interruptions:
          type: integer
        started_at:
          type: string
          format: date-time
        finished_at:
          type: string
          format: date-time
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
      - id
      - environment
      - selection
      - reference_date
      - status
      - created_by
      - created_at
    ProviderRequest:
      type: object
      description: One paid provider request, journaled before it is sent (req 206).
      properties:
        id:
          type: string
          format: uuid
        batch:
          type: string
          format: uuid
        stage:
          type: string
          enum:
          - ocr_page
          - reading
          - card_wording
        provider:
          type: string
          enum:
          - openrouter
          - gemini
        request_hash:
          type: string
        provider_id:
          type: string
        status:
          type: string
          enum:
          - submitted
          - completed
          - failed
        answer_uri:
          type: string
        input_tokens:
          type: integer
        output_tokens:
          type: integer
        cost_micros:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - batch
      - stage
      - provider
      - request_hash
      - status
      - created_at
      - updated_at
    ExtractionRun:
      type: object
      description: 'One immutable result: a call revision or an OCR page (req 207).'
      properties:
        id:
          type: string
          format: uuid
        batch:
          type: string
          format: uuid
        kind:
          type: string
          enum:
          - CallRevision
          - OcrPage
        approach:
          type: string
        model:
          type: string
        prompt_version:
          type: string
        input_hash:
          type: string
        status:
          type: string
          enum:
          - completed
          - failed
        input_tokens:
          type: integer
        output_tokens:
          type: integer
        duration_ms:
          type: integer
        created_at:
          type: string
          format: date-time
        call:
          type: string
          description: CallRevision only.
        record:
          $ref: '#/components/schemas/VerifiedRecord'
        readings:
          type: object
          additionalProperties: true
        source_coverage:
          type: object
          additionalProperties: true
        outcome:
          type: string
          enum:
          - record
          - failed
        document:
          type: string
          description: 'OcrPage only: SHA-256.'
        page_number:
          type: integer
        ocr_model:
          type: string
      required:
      - id
      - kind
      - approach
      - model
      - prompt_version
      - input_hash
      - status
      - created_at
    Municipality:
      type: object
      description: The official ISTAT crosswalk (req 210).
      properties:
        istat_code:
          type: string
        name:
          type: string
        province_code:
          type: string
        province:
          type: string
        region_code:
          type: string
        region:
          type: string
        postal_codes:
          type: array
          items:
            type: string
      required:
      - istat_code
      - name
      - province_code
      - province
      - region_code
      - region
    FundingCallSourceInput:
      type: object
      description: Adds or changes a row of the register; a verified row needs a verification date.
      properties:
        source_id:
          type: string
          description: Stable kebab-case identifier.
        level:
          type: string
          enum:
          - european
          - italian
          - regional
          - local
        publisher:
          type: string
        publisher_type:
          type: string
          enum:
          - ministry
          - paying_agency
          - development_agency
          - eu_body
          - directory
          - region
          - gal
          - chamber
          - municipality
          - province
          - mountain_community
          - park
          - other
        territories:
          type: array
          items:
            type: string
        url:
          type: string
          format: uri
        page_type:
          type: string
          enum:
          - calls
          - calendar
          - updates
          - bulletin
          - scheme
          - directory
        scope_notes:
          type: string
        discovered_from:
          type: string
        last_verified_at:
          type: string
          format: date
        status:
          type: string
          enum:
          - verified
          - needs_review
          - blocked
          - retired
      required:
      - source_id
      - level
      - publisher
      - publisher_type
      - url
      - page_type
      - status
    GrantCollectionInput:
      type: object
      description: 'Registers a collection: validates it, matches its dossiers with the identities file and writes
        calls, documents and associations in one transaction. `dry_run` only reports what would change.'
      properties:
        path:
          type: string
        window_start:
          type: string
          format: date
        identities:
          type: object
          additionalProperties: true
          description: Dossier path to call id, or null for a new call.
        dry_run:
          type: boolean
      required:
      - path
      - window_start
      - identities
    GrantCollectionReport:
      type: object
      description: What a registration added or would add, and what was registered differently before.
      properties:
        collection:
          $ref: '#/components/schemas/GrantCollection'
        added:
          type: object
          additionalProperties: true
        registered_but_different:
          type: array
          items:
            type: object
            additionalProperties: true
        problems:
          type: array
          items:
            type: string
      required:
      - collection
      - added
      - problems
    HoldRequest:
      type: object
      description: Withdraws a call from publication, or releases it.
      properties:
        hold:
          type: boolean
        reason:
          type: string
      required:
      - hold
    RestoreRequest:
      type: object
      description: Selects an earlier revision of the call; history is never deleted.
      properties:
        revision:
          type: string
          format: uuid
      required:
      - revision
    PublishRequest:
      type: object
      description: Publishes every revision of a batch at once, keeping what they replaced; `revert` puts them back.
      properties:
        batch:
          type: string
          format: uuid
        revert:
          type: boolean
      required:
      - batch
    GrantBatchInput:
      type: object
      description: 'Launches a batch on a selection, or the next part of a run that fits one batch (`next`). Limits:
        100 calls, 1,000 pairs, 500 OCR pages. Buys nothing until the worker runs.'
      properties:
        selection:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Call id to document hashes.
        reference_date:
          type: string
          format: date
        next:
          type: boolean
      required:
      - selection
      - reference_date
    BatchForecast:
      type: object
      description: What a launch would do, from saved page text, buying nothing.
      properties:
        calls_kept:
          type: integer
        skipped:
          type: array
          items:
            type: object
            properties:
              call:
                type: string
              reason:
                type: string
            required:
            - call
            - reason
        texts_to_prepare:
          type: integer
        batches:
          type: array
          items:
            type: integer
      required:
      - calls_kept
      - skipped
      - texts_to_prepare
      - batches
    SearchAreaAssignmentInput:
      type: object
      description: A reviewed assignment; the audit script checks every code exists before it is kept.
      properties:
        calls:
          type: array
          items:
            type: string
        level:
          type: string
          enum:
          - region
          - province
          - municipality
        codes:
          type: array
          items:
            type: string
        sources:
          type: array
          items:
            type: string
        note:
          type: string
      required:
      - calls
      - level
      - codes
      - sources
      - note
  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.'
