openapi: 3.0.3
info:
  title: Console API
  version: 1.0.0
  description: Central control plane API for the Dataerai platform.
servers:
- url: https://{server}
  description: Your Dataerai deployment (the API is served under /api)
  variables:
    server:
      default: your-deployment.dataerai.com
      description: Host of your Dataerai deployment
paths:
  /api/admin/users/:
    get:
      operationId: admin_users_list
      description: "GET /api/admin/users/ — paginated, sysadmin-only user list.\n\nQuery params:\n    ``q`` — case-insensitive partial match across name and email.\n    ``include_deactivated`` — truthy to include ``is_active=False`` rows\n        (default false).\n    ``page`` / ``page_size`` — DRF pagination knobs."
      parameters:
      - in: query
        name: include_deactivated
        schema:
          type: boolean
      - in: query
        name: page
        schema:
          type: integer
      - in: query
        name: page_size
        schema:
          type: integer
      - in: query
        name: q
        schema:
          type: string
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedAdminUserList'
          description: ''
  /api/admin/users/{id}/:
    get:
      operationId: admin_users_detail
      description: 'GET / PATCH /api/admin/users/{id}/ — sysadmin-only user detail.


        PATCH accepts ``is_active`` and ``is_system_admin``; every other field

        is silently ignored. The last-active-sysadmin guard refuses any change

        that would leave the system with zero active sysadmins.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminUserDetail'
          description: ''
    patch:
      operationId: admin_users_update
      description: 'GET / PATCH /api/admin/users/{id}/ — sysadmin-only user detail.


        PATCH accepts ``is_active`` and ``is_system_admin``; every other field

        is silently ignored. The last-active-sysadmin guard refuses any change

        that would leave the system with zero active sysadmins.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedAdminUserPatch'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedAdminUserPatch'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedAdminUserPatch'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminUserDetail'
          description: ''
  /api/admin/users/{id}/organizations/:
    post:
      operationId: admin_users_org_add
      description: 'POST /api/admin/users/{id}/organizations/ — attach a user to an org.


        Body: ``{organization_id, role?}``. ``role`` defaults to ``member``.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminUserOrgAdd'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AdminUserOrgAdd'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AdminUserOrgAdd'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          description: No response body
  /api/admin/users/{id}/organizations/{org_pk}/:
    patch:
      operationId: admin_users_org_role_change
      description: 'PATCH / DELETE /api/admin/users/{id}/organizations/{org_id}/ —

        change role on or remove an existing membership.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: org_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedAdminUserOrgRole'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedAdminUserOrgRole'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedAdminUserOrgRole'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          description: No response body
    delete:
      operationId: admin_users_org_remove
      description: 'PATCH / DELETE /api/admin/users/{id}/organizations/{org_id}/ —

        change role on or remove an existing membership.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: org_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/allocations/:
    get:
      operationId: api_allocations_list
      parameters:
      - in: query
        name: organization_id
        schema:
          type: string
        description: Return all allocations whose owner is a member of this org, plus the org-level allocation. Requires sysadmin or org-admin.
      - in: query
        name: owner_id
        schema:
          type: string
      - in: query
        name: owner_type
        schema:
          type: string
        description: user, project, or organization
      - in: query
        name: repository_id
        schema:
          type: string
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Allocation'
          description: ''
    post:
      operationId: allocations_create
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AllocationCreate'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AllocationCreate'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AllocationCreate'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Allocation'
          description: ''
  /api/allocations/{id}/:
    get:
      operationId: api_allocations_retrieve
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Allocation'
          description: ''
    patch:
      operationId: api_allocations_partial_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedAllocationLimit'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedAllocationLimit'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedAllocationLimit'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Allocation'
          description: ''
    delete:
      operationId: api_allocations_destroy
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/allocations/{id}/default/:
    post:
      operationId: api_allocations_default_create
      description: 'POST /api/allocations/{id}/default/


        Designate this allocation as the default for its owner (project or user).

        Permitted for: sysadmin, project admin, or org admin of the project''s org.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Allocation'
          description: ''
  /api/assets/:
    get:
      operationId: assets_list
      parameters:
      - in: query
        name: access_scope
        schema:
          type: string
        description: Use 'home' to include direct, organization, and public-access assets.
      - in: query
        name: collection_id
        schema:
          type: string
      - in: query
        name: cursor
        schema:
          type: string
        description: Opaque cursor from a previous page response.
      - in: query
        name: limit
        schema:
          type: integer
        description: Max assets to return. Default 100, max 1000.
      - in: query
        name: locked
        schema:
          type: boolean
      - in: query
        name: metadata
        schema:
          type: array
          items:
            type: string
        description: Metadata filter as key:value (containment) or bare key (existence). Repeatable; AND logic.
      - in: query
        name: ordering
        schema:
          type: string
        description: Ignored by cursor pagination. Results are always ordered by -is_starred, -created_at, id.
        deprecated: true
      - in: query
        name: owner_id
        schema:
          type: string
      - in: query
        name: owner_type
        schema:
          type: string
      - in: query
        name: q
        schema:
          type: string
        description: Case-insensitive substring filter on asset title or alias.
      - in: query
        name: record_type
        schema:
          type: string
        description: Asset type enum value. Comma-separated values use OR logic.
      - in: query
        name: tags
        schema:
          type: string
        description: Comma-separated tags to filter by
      - in: query
        name: title
        schema:
          type: array
          items:
            type: string
        description: Exact asset title filter. Repeatable; OR logic.
      - in: query
        name: title_prefix
        schema:
          type: string
        description: Case-insensitive asset-title prefix filter.
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          headers:
            X-Page-Limit:
              schema:
                type: integer
              description: Effective server-clamped page size used for this response.
              required: true
            X-Has-More:
              schema:
                type: string
                enum:
                - 'false'
                - 'true'
              description: Whether another cursor page may be available.
              required: true
            X-Next-Cursor:
              schema:
                type: string
              description: Opaque cursor to pass as the next request cursor when X-Has-More is true.
            X-Scan-Cap-Hit:
              schema:
                type: string
                enum:
                - 'true'
              description: Present with value true when server-side post-filter scanning reached its safety cap.
            X-Scan-Scanned:
              schema:
                type: integer
              description: Number of rows examined before X-Scan-Cap-Hit was set.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Asset'
          description: ''
    post:
      operationId: assets_create
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssetWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Asset'
          description: ''
  /api/assets/{id}/:
    get:
      operationId: assets_retrieve
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Asset'
          description: ''
    patch:
      operationId: assets_partial_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedAssetPatch'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedAssetPatch'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedAssetPatch'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Asset'
          description: ''
    delete:
      operationId: assets_destroy
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/assets/{id}/content/:
    get:
      operationId: asset_content_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssetContent'
          description: ''
    post:
      operationId: asset_content_create
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetContentWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssetContentWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetContentWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetContent'
          description: ''
  /api/assets/{id}/content/{content_pk}/:
    get:
      operationId: asset_content_retrieve
      parameters:
      - in: path
        name: content_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetContent'
          description: ''
    delete:
      operationId: asset_content_destroy
      parameters:
      - in: path
        name: content_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/assets/{id}/content/{content_pk}/extract-metadata/:
    post:
      operationId: asset_content_extract_metadata
      description: 'Force a (re-)extraction of metadata for an AssetContent.


        Runs synchronously and returns the updated record. Permission:

        WRITE_METADATA on the parent Asset. Returns 503 when metadata

        extraction is disabled on this deployment.'
      parameters:
      - in: path
        name: content_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetContent'
          description: ''
        '404':
          description: No response body
        '403':
          description: No response body
        '503':
          description: No response body
  /api/assets/{id}/location/:
    get:
      operationId: assets_location
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetLocation'
          description: ''
  /api/assets/{id}/lock/:
    post:
      operationId: assets_lock
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetLock'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssetLock'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetLock'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Asset'
          description: ''
  /api/assets/{id}/markdown-note/:
    get:
      operationId: asset_markdown_note_get
      description: 'Single free-form markdown note per asset.


        Permissions reuse the existing ``READ_NOTES`` / ``WRITE_NOTES`` flags —

        callers who can already see comments on the asset can also see this note.


        PUT semantics: idempotent upsert. The first PUT on an asset creates the

        note (201) and stamps ``author = request.user``. Subsequent PUTs update

        only the ``content`` field (200) and **do NOT refresh the author**.

        Authorship records who originally wrote the note, not who last edited it

        — preserving history of who introduced the content. If a per-edit author

        trail becomes a requirement, add an ``updated_by`` FK; do not silently

        overwrite ``author`` on edit.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetMarkdownNote'
          description: ''
        '404':
          description: No response body
    put:
      operationId: asset_markdown_note_upsert
      description: 'Single free-form markdown note per asset.


        Permissions reuse the existing ``READ_NOTES`` / ``WRITE_NOTES`` flags —

        callers who can already see comments on the asset can also see this note.


        PUT semantics: idempotent upsert. The first PUT on an asset creates the

        note (201) and stamps ``author = request.user``. Subsequent PUTs update

        only the ``content`` field (200) and **do NOT refresh the author**.

        Authorship records who originally wrote the note, not who last edited it

        — preserving history of who introduced the content. If a per-edit author

        trail becomes a requirement, add an ``updated_by`` FK; do not silently

        overwrite ``author`` on edit.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetMarkdownNoteWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssetMarkdownNoteWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetMarkdownNoteWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetMarkdownNote'
          description: ''
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetMarkdownNote'
          description: ''
    delete:
      operationId: asset_markdown_note_delete
      description: 'Single free-form markdown note per asset.


        Permissions reuse the existing ``READ_NOTES`` / ``WRITE_NOTES`` flags —

        callers who can already see comments on the asset can also see this note.


        PUT semantics: idempotent upsert. The first PUT on an asset creates the

        note (201) and stamps ``author = request.user``. Subsequent PUTs update

        only the ``content`` field (200) and **do NOT refresh the author**.

        Authorship records who originally wrote the note, not who last edited it

        — preserving history of who introduced the content. If a per-edit author

        trail becomes a requirement, add an ``updated_by`` FK; do not silently

        overwrite ``author`` on edit.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
        '404':
          description: No response body
  /api/assets/{id}/migrations/:
    get:
      operationId: asset_migrations_list
      description: GET /api/assets/{id}/migrations/ — per-asset migration history.
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssetBucketMigration'
          description: ''
  /api/assets/{id}/migrations/{mid}/retry/:
    post:
      operationId: asset_migration_retry
      description: 'POST /api/assets/{pk}/migrations/{mid}/retry/ — owner-accessible retry.


        Flips a ``failed`` migration back to ``pending`` so the worker can

        pick it up on its next poll. Requires WRITE_CONTENT on the asset

        (byte movement is a content-level action). ``asset.is_migrating``

        is unchanged — it was already True when the row failed.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: mid
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetBucketMigration'
          description: ''
  /api/assets/{id}/notes/:
    get:
      operationId: asset_notes_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Note'
          description: ''
    post:
      operationId: asset_notes_create
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoteWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/NoteWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/NoteWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Note'
          description: ''
  /api/assets/{id}/permissions/:
    get:
      operationId: api_assets_permissions_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PermissionEntry'
          description: ''
    put:
      operationId: api_assets_permissions_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PermissionEntry'
          description: ''
  /api/assets/{id}/relationships/:
    get:
      operationId: assets_relationships_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssetRelationship'
          description: ''
    post:
      operationId: assets_relationships_create
      description: 'Create an OUTGOING relationship from asset ``pk`` to ``to_asset_id``.


        Authoring a link is a metadata write on the source, so the caller needs

        WRITE_METADATA on ``pk``; they must also be able to see the target

        (READ_METADATA on ``to_asset``) so links can''t probe hidden assets.

        Self-links and exact duplicates (same from/to/type) are rejected.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetRelationshipWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssetRelationshipWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetRelationshipWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetRelationship'
          description: ''
  /api/assets/{id}/star/:
    post:
      operationId: assets_star
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
    delete:
      operationId: assets_unstar
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/assets/permissions/bulk-merge/:
    post:
      operationId: assets_permissions_bulk_merge
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetPermissionBulkMerge'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssetPermissionBulkMerge'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetPermissionBulkMerge'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/assets/permissions/intersection/:
    post:
      operationId: assets_permissions_intersection
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetPermissionIntersectionRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssetPermissionIntersectionRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetPermissionIntersectionRequest'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PermissionEntry'
          description: ''
  /api/assets/query/:
    post:
      operationId: assets_query
      description: POST /api/assets/query/ — structured metadata query (Phase 1 DSL).
      parameters:
      - in: query
        name: cursor
        schema:
          type: string
        description: Opaque cursor from a previous page response.
      - in: query
        name: limit
        schema:
          type: integer
        description: Max assets to return. Default 100, max 1000.
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetQueryRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssetQueryRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetQueryRequest'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          headers:
            X-Page-Limit:
              schema:
                type: integer
              description: Effective server-clamped page size used for this response.
              required: true
            X-Has-More:
              schema:
                type: string
                enum:
                - 'false'
                - 'true'
              description: Whether another cursor page may be available.
              required: true
            X-Next-Cursor:
              schema:
                type: string
              description: Opaque cursor to pass as the next request cursor when X-Has-More is true.
            X-Scan-Cap-Hit:
              schema:
                type: string
                enum:
                - 'true'
              description: Present with value true when server-side post-filter scanning reached its safety cap.
            X-Scan-Scanned:
              schema:
                type: integer
              description: Number of rows examined before X-Scan-Cap-Hit was set.
            X-Post-Filter:
              schema:
                type: string
                enum:
                - 'true'
              description: Present with value true when exact metadata post-filtering was applied; the response body can be empty while X-Has-More is true.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Asset'
          description: ''
  /api/collections/:
    get:
      operationId: collections_list
      parameters:
      - in: query
        name: access_scope
        schema:
          type: string
        description: Use 'home' to include direct, organization, and public-access collections.
      - in: query
        name: owner_id
        schema:
          type: string
      - in: query
        name: owner_type
        schema:
          type: string
      - in: query
        name: parent_id
        schema:
          type: string
      - in: query
        name: q
        schema:
          type: string
        description: Case-insensitive substring filter on collection title or alias.
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Collection'
          description: ''
    post:
      operationId: collections_create
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CollectionWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CollectionWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CollectionWrite'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Collection'
          description: ''
  /api/collections/{id}/:
    get:
      operationId: collections_retrieve
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Collection'
          description: ''
    patch:
      operationId: collections_partial_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedCollectionWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedCollectionWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedCollectionWrite'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Collection'
          description: ''
    delete:
      operationId: api_collections_destroy
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/collections/{id}/assets/:
    get:
      operationId: collection_assets_list
      description: List assets attached to a collection after the collection LIST gate.
      parameters:
      - in: query
        name: cursor
        schema:
          type: string
        description: Opaque cursor from a previous page response.
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      - in: query
        name: limit
        schema:
          type: integer
        description: Max assets to return. Default 100, max 1000.
      - in: query
        name: ordering
        schema:
          type: string
          enum:
          - -created_at
          - -creator
          - -title
          - -updated_at
          - created_at
          - creator
          - title
          - updated_at
        description: Optional current-collection file ordering.
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          headers:
            X-Page-Limit:
              schema:
                type: integer
              description: Effective server-clamped page size used for this response.
              required: true
            X-Has-More:
              schema:
                type: string
                enum:
                - 'false'
                - 'true'
              description: Whether another cursor page may be available.
              required: true
            X-Next-Cursor:
              schema:
                type: string
              description: Opaque cursor to pass as the next request cursor when X-Has-More is true.
            X-Scan-Cap-Hit:
              schema:
                type: string
                enum:
                - 'true'
              description: Present with value true when server-side post-filter scanning reached its safety cap.
            X-Scan-Scanned:
              schema:
                type: integer
              description: Number of rows examined before X-Scan-Cap-Hit was set.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Asset'
          description: ''
    post:
      operationId: collection_assets_add
      description: List assets attached to a collection after the collection LIST gate.
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CollectionAssetsAddRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CollectionAssetsAddRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CollectionAssetsAddRequest'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Asset'
          description: ''
  /api/collections/{id}/assets/{asset_pk}/:
    delete:
      operationId: collection_asset_remove
      parameters:
      - in: path
        name: asset_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/collections/{id}/breadcrumb-path/:
    get:
      operationId: collection_breadcrumb_path
      parameters:
      - in: query
        name: ancestor_ids
        schema:
          type: array
          items:
            type: string
            format: uuid
        description: Ordered ancestor collection ids preceding the target collection.
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      - in: query
        name: project_id
        schema:
          type: string
          format: uuid
        description: Project context for /p routes.
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CollectionBreadcrumbPathSegment'
          description: ''
  /api/collections/{id}/edges/:
    get:
      operationId: collection_edges_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Collection'
          description: ''
    post:
      operationId: collection_edges_add
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CollectionEdgesAddRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CollectionEdgesAddRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CollectionEdgesAddRequest'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Collection'
          description: ''
    delete:
      operationId: collection_edges_remove
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/collections/{id}/notes/:
    get:
      operationId: collection_notes_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CollectionNote'
          description: ''
  /api/collections/{id}/permissions/:
    get:
      operationId: api_collections_permissions_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PermissionEntry'
          description: ''
    put:
      operationId: api_collections_permissions_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PermissionEntry'
          description: ''
  /api/collections/{id}/star/:
    post:
      operationId: collections_star
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
    delete:
      operationId: collections_unstar
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/datasets/:
    get:
      operationId: api_datasets_list
      description: 'GET /datasets/ — list visible datasets.

        POST /datasets/ — promote an AssetContent into a new Dataset.'
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Dataset'
          description: ''
    post:
      operationId: api_datasets_create
      description: 'GET /datasets/ — list visible datasets.

        POST /datasets/ — promote an AssetContent into a new Dataset.'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DatasetCreate'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/DatasetCreate'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/DatasetCreate'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dataset'
          description: ''
  /api/datasets/{dataset_pk}/versions/:
    post:
      operationId: api_datasets_versions_create
      description: POST /datasets/{datasetId}/versions/ — append a new version.
      parameters:
      - in: path
        name: dataset_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DatasetVersionCreate'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/DatasetVersionCreate'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/DatasetVersionCreate'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatasetVersion'
          description: ''
  /api/datasets/{dataset_pk}/versions/{version_pk}/arrays/{array_name}/chunks/{chunk_path}:
    get:
      operationId: api_datasets_versions_arrays_chunks_retrieve
      description: 'GET /datasets/{dataset_id}/versions/{version_id}/arrays/{array_name}/chunks/{chunk_path}


        Returns 503 + Retry-After while real Zarr bytes are

        deferred-pending-zarr. Once zarr-python lands the view 302s to a

        presigned S3 URL — clients never see raw bucket / key tuples.


        The full path through the URL ensures every request goes through

        the per-version visibility check; there is no direct-to-S3 path.'
      parameters:
      - in: path
        name: array_name
        schema:
          type: string
        required: true
      - in: path
        name: chunk_path
        schema:
          type: string
        required: true
      - in: path
        name: dataset_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: version_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '503':
          description: No response body
        '400':
          description: No response body
        '404':
          description: No response body
  /api/datasets/{dataset_pk}/versions/{version_pk}/arrow/sample/:
    get:
      operationId: api_datasets_versions_arrow_sample_retrieve
      description: "GET /datasets/{dataset_id}/versions/{version_id}/arrow/sample\n\nReturns a sample of the version's tabular data. JSON envelope by\ndefault. Requesting the Arrow IPC stream via ``Accept:\napplication/vnd.apache.arrow.stream`` currently returns 503 with a\n``Retry-After`` header — Arrow output is unavailable on this\nserver; request ``application/json`` for the JSON envelope.\n\nQuery params:\n  size    int   1..100_000   default 1000\n  offset  int   ≥ 0          default 0\n  columns CSV   subset       default = all columns"
      parameters:
      - in: query
        name: columns
        schema:
          type: string
      - in: path
        name: dataset_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: query
        name: format
        schema:
          type: string
          enum:
          - arrow
          - json
      - in: query
        name: offset
        schema:
          type: integer
      - in: query
        name: size
        schema:
          type: integer
      - in: path
        name: version_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrowSampleJSON'
            application/vnd.apache.arrow.stream:
              schema:
                $ref: '#/components/schemas/ArrowSampleJSON'
          description: ''
        '400':
          description: No response body
        '413':
          description: No response body
        '503':
          description: No response body
  /api/datasets/{dataset_pk}/versions/{version_pk}/artifacts/:
    get:
      operationId: api_datasets_versions_artifacts_list
      description: 'GET /datasets/{datasetId}/versions/{versionId}/artifacts —

        lists artifacts produced for the version.'
      parameters:
      - in: path
        name: dataset_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: version_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ArtifactRegistry'
          description: ''
  /api/datasets/{dataset_pk}/versions/{version_pk}/manifest/:
    get:
      operationId: api_datasets_versions_manifest_retrieve
      description: 'GET /datasets/{dataset_id}/versions/{version_id}/manifest


        Returns the canonical manifest — the single source of truth the

        frontend reads to decide what visualizations / capabilities the

        version exposes. Cached as a `dataset.manifest` artifact;

        regenerated when artifacts have changed since last cache.


        Emits a content-derived ETag so polling clients can short-circuit

        via ``If-None-Match`` and avoid re-downloading an unchanged body.'
      parameters:
      - in: path
        name: dataset_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: version_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/datasets/{dataset_pk}/versions/{version_pk}/preprocess/:
    post:
      operationId: api_datasets_versions_preprocess_create
      description: 'POST /datasets/{datasetId}/versions/{versionId}/preprocess —

        enqueue a preprocessing job.


        Allowed source states: UPLOADED, PREPROCESSING_FAILED. Anything

        else returns 409. On success, returns 202 with the queued job;

        poll the version status endpoint to follow the QUEUED → RUNNING

        → SUCCEEDED|FAILED transitions.'
      parameters:
      - in: path
        name: dataset_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: version_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PreprocessRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PreprocessRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PreprocessRequest'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PreprocessingJob'
          description: ''
  /api/datasets/{dataset_pk}/versions/{version_pk}/status/:
    get:
      operationId: api_datasets_versions_status_retrieve
      description: 'GET /datasets/{datasetId}/versions/{versionId}/status —

        returns version status, latest job, recent errors.'
      parameters:
      - in: path
        name: dataset_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: version_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatasetVersionStatus'
          description: ''
  /api/datasets/{dataset_pk}/versions/{version_pk}/tiles/{view_name}/{z}/{x}/{y}.{ext}:
    get:
      operationId: api_datasets_versions_tiles_._retrieve
      description: 'GET /datasets/{dataset_id}/versions/{version_id}/tiles/{view_name}/{z}/{x}/{y}.{ext}


        Serves tiles for a named tile view of the version. Requires

        authentication and per-version dataset visibility. ``view_name``

        must exist in the version''s tiles manifest, ``z`` must not exceed

        the maximum zoom level, and ``ext`` must match the view type

        (``png`` for raster views, ``pbf`` for vector views); mismatches

        return 400 or 404. Returns 503 with a ``Retry-After`` header when

        tile rendering is unavailable on the server.'
      parameters:
      - in: path
        name: dataset_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: ext
        schema:
          type: string
        required: true
      - in: path
        name: version_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: view_name
        schema:
          type: string
        required: true
      - in: path
        name: x
        schema:
          type: integer
        required: true
      - in: path
        name: y
        schema:
          type: integer
        required: true
      - in: path
        name: z
        schema:
          type: integer
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '503':
          description: No response body
        '400':
          description: No response body
        '404':
          description: No response body
  /api/datasets/{id}/:
    get:
      operationId: api_datasets_retrieve
      description: GET /datasets/{id}/ — dataset detail with all versions.
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dataset'
          description: ''
  /api/datasets/{id}/storage-usage/:
    get:
      operationId: api_datasets_storage_usage_retrieve
      description: 'GET /datasets/{id}/storage-usage — sum of artifact sizes by

        type for a single dataset. Auth required + dataset visibility.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/funding-agencies/:
    get:
      operationId: api_funding_agencies_list
      description: GET / POST /api/funding-agencies/
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FundingAgency'
          description: ''
    post:
      operationId: api_funding_agencies_create
      description: GET / POST /api/funding-agencies/
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FundingAgency'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FundingAgency'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FundingAgency'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FundingAgency'
          description: ''
  /api/funding-agencies/{id}/:
    get:
      operationId: api_funding_agencies_retrieve
      description: GET / PATCH / DELETE /api/funding-agencies/<uuid:pk>/
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FundingAgency'
          description: ''
    patch:
      operationId: api_funding_agencies_partial_update
      description: GET / PATCH / DELETE /api/funding-agencies/<uuid:pk>/
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedFundingAgency'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedFundingAgency'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedFundingAgency'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FundingAgency'
          description: ''
    delete:
      operationId: api_funding_agencies_destroy
      description: GET / PATCH / DELETE /api/funding-agencies/<uuid:pk>/
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/grants/:
    get:
      operationId: api_grants_list
      description: 'GET / POST /api/grants/


        Filters: ?q (substring on title/grant_id/contact_pi_name),

        ?registry_source, ?fiscal_year, ?funding_agency_id, ?project_id,

        ?is_latest (default true; pass false/0/no to include historical versions).'
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GrantRead'
          description: ''
    post:
      operationId: api_grants_create
      description: 'GET / POST /api/grants/


        Filters: ?q (substring on title/grant_id/contact_pi_name),

        ?registry_source, ?fiscal_year, ?funding_agency_id, ?project_id,

        ?is_latest (default true; pass false/0/no to include historical versions).'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GrantWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/GrantWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/GrantWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantRead'
          description: ''
  /api/grants/{id}/:
    get:
      operationId: api_grants_retrieve
      description: GET / PATCH / DELETE /api/grants/<uuid:pk>/
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantRead'
          description: ''
    patch:
      operationId: api_grants_partial_update
      description: GET / PATCH / DELETE /api/grants/<uuid:pk>/
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedGrantWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedGrantWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedGrantWrite'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GrantRead'
          description: ''
    delete:
      operationId: api_grants_destroy
      description: GET / PATCH / DELETE /api/grants/<uuid:pk>/
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/groups/:
    get:
      operationId: groups_list
      parameters:
      - in: query
        name: member_id
        schema:
          type: string
        description: User id or 'me'
      - in: query
        name: name
        schema:
          type: string
        description: Case-insensitive substring match on group name.
      - in: query
        name: organization_id
        schema:
          type: string
      - in: query
        name: type
        schema:
          type: string
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Group'
          description: ''
    post:
      operationId: groups_create
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/GroupWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/GroupWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
          description: ''
  /api/groups/{id}/:
    get:
      operationId: groups_retrieve
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
          description: ''
    patch:
      operationId: groups_partial_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedGroupPatch'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedGroupPatch'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedGroupPatch'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
          description: ''
    delete:
      operationId: groups_destroy
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/groups/{id}/assignments/:
    get:
      operationId: group_assignments_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GroupAssignment'
          description: ''
    delete:
      operationId: group_assignments_remove
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/groups/{id}/members/:
    get:
      operationId: group_members_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GroupMember'
          description: ''
    post:
      operationId: group_members_add
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupMemberAdd'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/GroupMemberAdd'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/GroupMemberAdd'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/groups/{id}/members/{user_pk}/:
    delete:
      operationId: group_members_remove
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: user_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/me/:
    get:
      operationId: api_me_retrieve
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Me'
          description: ''
    patch:
      operationId: api_me_partial_update
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedMeUpdate'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedMeUpdate'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedMeUpdate'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Me'
          description: ''
  /api/me/avatar/:
    post:
      operationId: api_me_avatar_create
      description: "POST /api/me/avatar/   multipart \"file\" (JPEG/PNG/WEBP/GIF, max 5 MB)\n                       → re-encodes to a 512×512 JPEG and stores it;\n                       returns the updated current-user profile.\nDELETE /api/me/avatar/ removes the stored avatar and clears the field;\n                       returns the updated current-user profile."
      tags:
      - api
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
              required:
              - file
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Me'
          description: ''
    delete:
      operationId: api_me_avatar_destroy
      description: "POST /api/me/avatar/   multipart \"file\" (JPEG/PNG/WEBP/GIF, max 5 MB)\n                       → re-encodes to a 512×512 JPEG and stores it;\n                       returns the updated current-user profile.\nDELETE /api/me/avatar/ removes the stored avatar and clears the field;\n                       returns the updated current-user profile."
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Me'
          description: ''
  /api/migrations/:
    get:
      operationId: migrations_list
      description: 'GET /api/migrations/ — all visible migrations for the caller.


        Scoped the same way as Transfers: the caller must have READ_METADATA on

        the underlying asset. Feeds the merged Transfers panel.'
      parameters:
      - in: query
        name: status
        schema:
          type: string
        description: Comma-separated list, e.g. "pending,in_progress".
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssetBucketMigration'
          description: ''
  /api/organizations/:
    get:
      operationId: api_organizations_list
      description: 'GET  /api/organizations/  — SysAdmin: all orgs; OrgAdmin: managed orgs.

        POST /api/organizations/  — SysAdmin only.'
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Organization'
          description: ''
    post:
      operationId: api_organizations_create
      description: 'GET  /api/organizations/  — SysAdmin: all orgs; OrgAdmin: managed orgs.

        POST /api/organizations/  — SysAdmin only.'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/OrganizationWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/OrganizationWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
          description: ''
  /api/organizations/{id}/:
    get:
      operationId: api_organizations_retrieve
      description: "GET   /api/organizations/{pk}/  — SysAdmin or any OrgMember.\nPATCH /api/organizations/{pk}/  — SysAdmin or OrgAdmin.\n    whitelisted_email_domains and globus_identity_provider_id are SysAdmin-only."
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
          description: ''
    patch:
      operationId: api_organizations_partial_update
      description: "GET   /api/organizations/{pk}/  — SysAdmin or any OrgMember.\nPATCH /api/organizations/{pk}/  — SysAdmin or OrgAdmin.\n    whitelisted_email_domains and globus_identity_provider_id are SysAdmin-only."
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedOrganizationWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedOrganizationWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedOrganizationWrite'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
          description: ''
  /api/organizations/{id}/members/:
    get:
      operationId: api_organizations_members_list
      description: 'GET  /api/organizations/{pk}/members/  — SysAdmin or any OrgMember.

        POST /api/organizations/{pk}/members/  — SysAdmin or OrgAdmin.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/OrganizationMember'
          description: ''
    post:
      operationId: api_organizations_members_create
      description: 'GET  /api/organizations/{pk}/members/  — SysAdmin or any OrgMember.

        POST /api/organizations/{pk}/members/  — SysAdmin or OrgAdmin.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationMemberWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/OrganizationMemberWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/OrganizationMemberWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationMember'
          description: ''
  /api/organizations/{id}/members/{user_pk}/:
    patch:
      operationId: api_organizations_members_partial_update
      description: 'PATCH  /api/organizations/{pk}/members/{user_pk}/  — change role.

        DELETE /api/organizations/{pk}/members/{user_pk}/  — remove member.

        SysAdmin or OrgAdmin only.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: user_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedOrganizationMemberWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedOrganizationMemberWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedOrganizationMemberWrite'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationMember'
          description: ''
    delete:
      operationId: api_organizations_members_destroy
      description: 'PATCH  /api/organizations/{pk}/members/{user_pk}/  — change role.

        DELETE /api/organizations/{pk}/members/{user_pk}/  — remove member.

        SysAdmin or OrgAdmin only.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: user_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/preview-metadata/:
    post:
      operationId: api_preview_metadata_create
      description: 'Run metadata extraction on a file uploaded directly via multipart form-data.


        Used by the upload dialog to show extracted metadata BEFORE the user

        clicks "Upload" to commit the asset. The file is written to a temp

        file in the pod, run through the adapter, and immediately deleted.


        Bandwidth cost: the file is uploaded twice — once here for preview,

        again to MinIO if the user confirms. Capped at

        ``METADATA_PREVIEW_MAX_BYTES`` (default 100 MB) to keep that cost bounded.'
      tags:
      - api
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PreviewMetadataMultipartRequest'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PreviewMetadataMultipartResponse'
          description: ''
        '400':
          description: No response body
        '413':
          description: No response body
        '503':
          description: No response body
  /api/projects/:
    get:
      operationId: api_projects_list
      parameters:
      - in: query
        name: access_scope
        schema:
          type: string
        description: Use 'home' to include direct, organization, and public-access projects.
      - in: query
        name: q
        schema:
          type: string
        description: Case-insensitive substring filter on project name.
      - in: query
        name: role
        schema:
          type: string
      - in: query
        name: scope
        schema:
          type: string
          enum:
          - direct
          - org
          - public
        description: Visibility scope. 'direct' (default) = direct grants; 'org' = via shared organization, no direct or public grant; 'public' = public-read, no direct grant.
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Project'
          description: ''
    post:
      operationId: api_projects_create
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProjectWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ProjectWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ProjectWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
          description: ''
  /api/projects/{id}/:
    get:
      operationId: api_projects_retrieve
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectDetail'
          description: ''
    patch:
      operationId: api_projects_partial_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedProjectWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedProjectWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedProjectWrite'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectDetail'
          description: ''
    delete:
      operationId: api_projects_destroy
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/projects/{id}/permissions/:
    get:
      operationId: api_projects_permissions_list
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PermissionEntry'
          description: ''
    put:
      operationId: api_projects_permissions_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PermissionReplace'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PermissionEntry'
          description: ''
  /api/projects/{id}/star/:
    post:
      operationId: projects_star
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
    delete:
      operationId: projects_unstar
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/projects/{project_pk}/members/:
    get:
      operationId: api_projects_members_list
      parameters:
      - in: path
        name: project_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProjectMember'
          description: ''
    post:
      operationId: api_projects_members_create
      parameters:
      - in: path
        name: project_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProjectMemberWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ProjectMemberWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ProjectMemberWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectMember'
          description: ''
  /api/projects/{project_pk}/members/{user_pk}/:
    patch:
      operationId: api_projects_members_partial_update
      parameters:
      - in: path
        name: project_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: user_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedProjectRole'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedProjectRole'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedProjectRole'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectMember'
          description: ''
    delete:
      operationId: api_projects_members_destroy
      parameters:
      - in: path
        name: project_pk
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: user_pk
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/repositories/:
    get:
      operationId: api_repositories_list
      parameters:
      - in: query
        name: owner_id
        schema:
          type: string
          format: uuid
        description: UUID of the owner (user or project) to filter by.
      - in: query
        name: owner_type
        schema:
          type: string
          enum:
          - project
          - user
        description: When provided with owner_id, filter to repositories where the specified owner has an Allocation. Caller must be the user or a member of the project.
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Repository'
          description: ''
    post:
      operationId: api_repositories_create
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RepositoryWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/RepositoryWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/RepositoryWrite'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Repository'
          description: ''
  /api/repositories/{id}/:
    get:
      operationId: api_repositories_retrieve
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Repository'
          description: ''
    patch:
      operationId: api_repositories_partial_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedRepositoryWrite'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedRepositoryWrite'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedRepositoryWrite'
      security:
      - cookieAuthCsrfExempt: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Repository'
          description: ''
    delete:
      operationId: api_repositories_destroy
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      - {}
      responses:
        '204':
          description: No response body
  /api/repositories/{id}/retry/:
    post:
      operationId: repositories_retry
      description: 'POST /api/repositories/{id}/retry/ — system-admin retry of a

        failed spawn. Reuses the stored ciphertext; the admin doesn''t

        re-submit keys.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Repository'
          description: ''
  /api/search/:
    get:
      operationId: assets_search
      parameters:
      - in: query
        name: collection
        schema:
          type: string
        description: Collection UUID to scope results
      - in: query
        name: creator
        schema:
          type: string
        description: Creator name or email (icontains)
      - in: query
        name: cursor
        schema:
          type: string
        description: Opaque cursor from a previous page response.
      - in: query
        name: id
        schema:
          type: string
        description: Asset UUID (exact) or alias (icontains)
      - in: query
        name: limit
        schema:
          type: integer
        description: Max assets to return. Default 100, max 1000.
      - in: query
        name: metadata
        schema:
          type: array
          items:
            type: string
        description: Metadata filter as key:value (containment) or bare key (existence). Repeatable; AND logic.
      - in: query
        name: ordering
        schema:
          type: string
        description: Ignored by cursor pagination. Results are always ordered by -is_starred, -created_at, id.
        deprecated: true
      - in: query
        name: q
        schema:
          type: string
        description: Text search across title, description, and alias
      - in: query
        name: record_type
        schema:
          type: string
        description: Asset type enum value. Comma-separated values use OR logic.
      - in: query
        name: search_metadata
        schema:
          type: boolean
        description: Opt in to scanning metadata values with ILIKE. Disables the GIN index — avoid on large datasets.
      - in: query
        name: tags
        schema:
          type: string
        description: Comma-separated tags (AND logic)
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          headers:
            X-Page-Limit:
              schema:
                type: integer
              description: Effective server-clamped page size used for this response.
              required: true
            X-Has-More:
              schema:
                type: string
                enum:
                - 'false'
                - 'true'
              description: Whether another cursor page may be available.
              required: true
            X-Next-Cursor:
              schema:
                type: string
              description: Opaque cursor to pass as the next request cursor when X-Has-More is true.
            X-Scan-Cap-Hit:
              schema:
                type: string
                enum:
                - 'true'
              description: Present with value true when server-side post-filter scanning reached its safety cap.
            X-Scan-Scanned:
              schema:
                type: integer
              description: Number of rows examined before X-Scan-Cap-Hit was set.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssetSearch'
          description: ''
  /api/transfers/:
    get:
      operationId: api_transfers_list
      parameters:
      - in: query
        name: asset_id
        schema:
          type: string
          format: uuid
      - in: query
        name: ordering
        schema:
          type: string
        description: Allowlisted ordering key; prefix with "-" for descending.
      - in: query
        name: origin
        schema:
          type: string
          enum:
          - all
          - system
          - user
        description: Defaults to "user". Pass "all" for debug/admin views.
      - in: query
        name: page
        schema:
          type: integer
      - in: query
        name: page_size
        schema:
          type: integer
      - in: query
        name: project
        schema:
          type: string
          format: uuid
      - in: query
        name: q
        schema:
          type: string
        description: Case-insensitive substring match on asset title.
      - in: query
        name: repository
        schema:
          type: string
          format: uuid
      - in: query
        name: status
        schema:
          type: string
        description: Comma-separated list, e.g. "pending,in_progress".
      - in: query
        name: type
        schema:
          type: string
          enum:
          - download
          - upload
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedTransferResponse'
          description: ''
    post:
      operationId: api_transfers_create
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransferInitiate'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TransferInitiate'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/TransferInitiate'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferInitiateResponse'
          description: ''
  /api/transfers/{id}/:
    get:
      operationId: api_transfers_retrieve
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transfer'
          description: ''
    patch:
      operationId: api_transfers_partial_update
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedTransferProgress'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedTransferProgress'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedTransferProgress'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transfer'
          description: ''
  /api/transfers/{id}/abort/:
    post:
      operationId: api_transfers_abort_create
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/transfers/{id}/complete/:
    post:
      operationId: api_transfers_complete_create
      description: "Finalize an upload transfer.\n\nOptional request body fields control the metadata-extraction behavior:\n\n* ``extracted_metadata`` (object) — pre-extracted metadata from the\n  staged-upload preview. When provided, persists this verbatim and\n  suppresses the post-commit auto-extraction hook.\n* ``skip_extraction`` (bool) — when ``true``, suppresses auto-extraction\n  and leaves metadata fields empty. The user explicitly opted out.\n\nWhen neither field is set, behavior is unchanged: the auto-extraction\ncompletion hook fires after commit. This preserves the contract for\ncallers (e.g. the electron app) that pre-date the staging UX."
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransferCompleteRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TransferCompleteRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/TransferCompleteRequest'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transfer'
          description: ''
  /api/transfers/{id}/credentials/:
    post:
      operationId: api_transfers_credentials_create
      description: Refresh credentials for a long-running transfer.
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferCredentialsResponse'
          description: ''
  /api/transfers/{id}/discard/:
    post:
      operationId: api_transfers_discard_create
      description: 'Cancel a staged upload and remove all traces of it.


        Deletes the uploaded bytes from the storage backend, removes the

        AssetContent row (which cascades the Transfer row away too). Use this

        when the user explicitly rejects a staged upload via the preview drawer.


        Distinct from /abort/, which preserves the AssetContent + Transfer for

        history (semantics: "transfer failed, may retry").'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
  /api/transfers/{id}/preview-metadata/:
    post:
      operationId: api_transfers_preview_metadata_create
      description: 'Run metadata extraction on a not-yet-completed upload, without persisting.


        Used by the staging UX: after the browser PUTs the file to MinIO but

        before calling /complete/, the UI fetches a metadata preview so the user

        can review/edit/discard before committing the asset.


        Source-size cap (``METADATA_PREVIEW_MAX_BYTES``, default 100 MB) keeps

        the preview path fast and avoids surprise multi-GB downloads from the

        repo agent into the console pod.'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferMetadataPreviewResponse'
          description: ''
        '413':
          description: No response body
        '404':
          description: No response body
        '503':
          description: No response body
  /api/transfers/filters/:
    get:
      operationId: api_transfers_filters_retrieve
      description: 'GET /api/transfers/filters/ — Project + Repository options for the filter popover.


        Derived from the same base queryset as ``GET /api/transfers/`` so

        every option surfaced here yields at least one row in the default

        list. Null project/repository rows are excluded.'
      parameters:
      - in: query
        name: origin
        schema:
          type: string
          enum:
          - all
          - system
          - user
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferFiltersResponse'
          description: ''
  /api/users/:
    get:
      operationId: users_list
      parameters:
      - in: query
        name: email
        schema:
          type: string
      - in: query
        name: name
        schema:
          type: string
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/UserSearch'
          description: ''
  /api/viz/cost/estimate/:
    post:
      operationId: api_viz_cost_estimate_create
      description: 'POST /viz/cost/estimate


        Validates the spec (structural + semantic) then returns a

        ``VizCostEstimate``. Same authentication, visibility, and

        readiness rules as POST /viz/safe-viz-spec/validate/.


        On failure: ``{is_valid: false, errors: [{path, error}]}`` —

        same envelope as the validate endpoint, so clients have a

        single error-handling path. On success: the flat

        ``VizCostEstimate`` body.'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              type: object
              additionalProperties: {}
          application/x-www-form-urlencoded:
            schema:
              type: object
              additionalProperties: {}
          multipart/form-data:
            schema:
              type: object
              additionalProperties: {}
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/viz/execute/:
    post:
      operationId: api_viz_execute_create
      description: 'POST /viz/execute — full viz pipeline.


        validate → plan → execute; returns the execution plan plus a

        Plotly figure envelope (``data``/``layout``/``config``). Executor

        lookup follows the plan''s ``mode``.


        Error statuses: 400 (validation failure), 410 (cached result no

        longer available), 413 (result exceeds the row/byte ceiling), 429

        (async-job quota exceeded), 501 (mode / artifact / source format

        not supported by this server), 504 (query exceeded the execution

        budget).


        Same authentication, visibility, and readiness rules as the other

        viz endpoints (e.g. POST /viz/safe-viz-spec/validate/).'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              type: object
              additionalProperties: {}
          application/x-www-form-urlencoded:
            schema:
              type: object
              additionalProperties: {}
          multipart/form-data:
            schema:
              type: object
              additionalProperties: {}
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/viz/metrics/:
    get:
      operationId: api_viz_metrics_retrieve
      description: 'GET /viz/metrics — return a snapshot of in-process counters

        and histograms recorded by the visualization pipeline. Auth

        required because per-dataset / per-user labels can hint at

        activity.'
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/viz/plan/:
    post:
      operationId: api_viz_plan_create
      description: 'POST /viz/plan — return the execution plan for a spec.


        Same authentication, visibility, readiness, and no-leak rules as

        POST /viz/safe-viz-spec/validate/ and POST /viz/cost/estimate/.

        On failure: the common ``{is_valid: false, errors: [{path,

        error}]}`` envelope.'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              type: object
              additionalProperties: {}
          application/x-www-form-urlencoded:
            schema:
              type: object
              additionalProperties: {}
          multipart/form-data:
            schema:
              type: object
              additionalProperties: {}
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/viz/rows/lookup/:
    post:
      operationId: api_viz_rows_lookup_create
      description: 'POST /viz/rows/lookup — resolve selected point IDs to row dicts.


        Accepts ``{"datasetId": ..., "versionId": ..., "ids": [int, ...]}``.

        Returns ``{"rows": [{"id": <int>, <visible-field>: <value>, ...}]}``.

        Selection size is capped at ``MAX_LOOKUP_IDS``; out-of-range IDs

        are silently dropped (the client gets fewer rows than requested).'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              type: object
              additionalProperties: {}
          application/x-www-form-urlencoded:
            schema:
              type: object
              additionalProperties: {}
          multipart/form-data:
            schema:
              type: object
              additionalProperties: {}
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/viz/safe-viz-spec/schema/:
    get:
      operationId: api_viz_safe_viz_spec_schema_retrieve
      description: 'GET /viz/safe-viz-spec/schema — returns the SafeVizSpec JSON schema.


        The frontend caches this for the session and uses it to drive

        form validation. Authentication required so the schema (and the

        enumerated module / scale lists) doesn''t leak via the public web.'
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/viz/safe-viz-spec/validate/:
    post:
      operationId: api_viz_safe_viz_spec_validate_create
      description: 'POST /viz/safe-viz-spec/validate — full validation pipeline.


        Runs structural and semantic checks against the referenced

        dataset version (which must be visible to the caller).

        Returns 200 with `{is_valid: true, errors: []}` on success or

        400 with `{is_valid: false, errors: [{path, error}]}` on failure.


        Hidden-field references receive the same generic "field not found"

        error as missing fields — never reveal that a field exists but is

        policy-blocked (the no-leak rule).'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              type: object
              additionalProperties: {}
          application/x-www-form-urlencoded:
            schema:
              type: object
              additionalProperties: {}
          multipart/form-data:
            schema:
              type: object
              additionalProperties: {}
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/geobound-country-sets/:
    get:
      operationId: api_geobound_country_sets_list
      description: 'GET / POST /api/geobound-country-sets/


        Shared global reference table of versioned country-code presets used by

        project geobound policies. READ (list) is open to any authenticated user

        so they can pick a set when configuring a project/org/profile default;

        CREATE is gated to system admins (``IsSystemAdminOrReadOnly``) so a tenant

        user cannot inject or re-point shared-corpus rows.'
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GeoBoundCountrySet'
          description: ''
    post:
      operationId: api_geobound_country_sets_create
      description: 'GET / POST /api/geobound-country-sets/


        Shared global reference table of versioned country-code presets used by

        project geobound policies. READ (list) is open to any authenticated user

        so they can pick a set when configuring a project/org/profile default;

        CREATE is gated to system admins (``IsSystemAdminOrReadOnly``) so a tenant

        user cannot inject or re-point shared-corpus rows.'
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GeoBoundCountrySet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/GeoBoundCountrySet'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/GeoBoundCountrySet'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeoBoundCountrySet'
          description: ''
  /api/geobound-country-sets/{id}/:
    get:
      operationId: api_geobound_country_sets_retrieve
      description: 'GET / PUT / PATCH / DELETE /api/geobound-country-sets/<uuid:pk>/


        READ (retrieve) open to any authenticated user; UPDATE/DELETE gated to

        system admins (``IsSystemAdminOrReadOnly``).'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeoBoundCountrySet'
          description: ''
    put:
      operationId: api_geobound_country_sets_update
      description: 'GET / PUT / PATCH / DELETE /api/geobound-country-sets/<uuid:pk>/


        READ (retrieve) open to any authenticated user; UPDATE/DELETE gated to

        system admins (``IsSystemAdminOrReadOnly``).'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GeoBoundCountrySet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/GeoBoundCountrySet'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/GeoBoundCountrySet'
        required: true
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeoBoundCountrySet'
          description: ''
    patch:
      operationId: api_geobound_country_sets_partial_update
      description: 'GET / PUT / PATCH / DELETE /api/geobound-country-sets/<uuid:pk>/


        READ (retrieve) open to any authenticated user; UPDATE/DELETE gated to

        system admins (``IsSystemAdminOrReadOnly``).'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedGeoBoundCountrySet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedGeoBoundCountrySet'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedGeoBoundCountrySet'
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeoBoundCountrySet'
          description: ''
    delete:
      operationId: api_geobound_country_sets_destroy
      description: 'GET / PUT / PATCH / DELETE /api/geobound-country-sets/<uuid:pk>/


        READ (retrieve) open to any authenticated user; UPDATE/DELETE gated to

        system admins (``IsSystemAdminOrReadOnly``).'
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - cookieAuthCsrfExempt: []
      responses:
        '204':
          description: No response body
components:
  schemas:
    ActionEnum:
      enum:
      - move
      - copy
      - delete
      type: string
      description: '* `move` - Move

        * `copy` - Copy

        * `delete` - Delete'
    AdminUserDetail:
      type: object
      description: 'Resolve ``user.person`` once per serialization pass.


        ``user.person`` memoizes per instance, but distinct users in a list are

        distinct instances — so a list serializer would still issue one

        ``Person`` query per row. When used ``many=True`` this mixin routes

        through :class:`_PersonReadThroughListSerializer`, which calls

        ``User.attach_persons`` to batch the whole page into a single query;

        the per-render ``context`` cache below then dedups the name+email

        double-read for each user.


        The context cache lives only for the lifetime of the serializer tree,

        so one ``.data`` render resolves each distinct user''s ``Person`` at

        most once and re-batches fresh on the next render.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        email:
          type: string
          readOnly: true
        name:
          type: string
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
          title: Active
          description: Designates whether this user should be treated as active. Unselect this instead of deleting accounts.
        is_system_admin:
          type: boolean
          readOnly: true
        organizations:
          type: array
          items:
            $ref: '#/components/schemas/AdminUserOrgMembership'
          readOnly: true
        date_joined:
          type: string
          format: date-time
          readOnly: true
        last_login:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        is_last_active_sysadmin:
          type: boolean
          readOnly: true
      required:
      - date_joined
      - email
      - id
      - is_active
      - is_last_active_sysadmin
      - is_system_admin
      - last_login
      - name
      - organizations
    AdminUserList:
      type: object
      description: 'Resolve ``user.person`` once per serialization pass.


        ``user.person`` memoizes per instance, but distinct users in a list are

        distinct instances — so a list serializer would still issue one

        ``Person`` query per row. When used ``many=True`` this mixin routes

        through :class:`_PersonReadThroughListSerializer`, which calls

        ``User.attach_persons`` to batch the whole page into a single query;

        the per-render ``context`` cache below then dedups the name+email

        double-read for each user.


        The context cache lives only for the lifetime of the serializer tree,

        so one ``.data`` render resolves each distinct user''s ``Person`` at

        most once and re-batches fresh on the next render.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        email:
          type: string
          readOnly: true
        name:
          type: string
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
          title: Active
          description: Designates whether this user should be treated as active. Unselect this instead of deleting accounts.
        is_system_admin:
          type: boolean
          readOnly: true
        organizations:
          type: array
          items:
            $ref: '#/components/schemas/AdminUserOrgMembership'
          readOnly: true
      required:
      - email
      - id
      - is_active
      - is_system_admin
      - name
      - organizations
    AdminUserOrgAdd:
      type: object
      properties:
        organization_id:
          type: string
          format: uuid
        role:
          allOf:
          - $ref: '#/components/schemas/OrgMemberRoleEnum'
          default: member
      required:
      - organization_id
    AdminUserOrgMembership:
      type: object
      description: 'The ``{id, name, role}`` tuple inside a user row''s ``organizations``

        list — surfaced as a typed schema for frontend codegen.'
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        role:
          $ref: '#/components/schemas/OrgMemberRoleEnum'
      required:
      - id
      - name
      - role
    Allocation:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        repository_id:
          type: string
          format: uuid
          readOnly: true
        repository_name:
          type: string
          readOnly: true
        owner_user:
          allOf:
          - $ref: '#/components/schemas/User'
          readOnly: true
        owner_project:
          allOf:
          - $ref: '#/components/schemas/AllocationProject'
          readOnly: true
        owner_project_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        owner_organization_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        parent_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        children_count:
          type: integer
          readOnly: true
        alias:
          type: string
          readOnly: true
        data_volume_limit:
          type: integer
          readOnly: true
        max_records:
          type: integer
          readOnly: true
        remaining_data_volume_limit:
          type: integer
          readOnly: true
        remaining_max_records:
          type: integer
          readOnly: true
        current_bytes:
          type: integer
          readOnly: true
        current_record_count:
          type: integer
          readOnly: true
        is_default:
          type: boolean
          readOnly: true
        pooled:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - alias
      - children_count
      - created_at
      - current_bytes
      - current_record_count
      - data_volume_limit
      - id
      - is_default
      - max_records
      - owner_organization_id
      - owner_project
      - owner_project_id
      - owner_user
      - parent_id
      - pooled
      - remaining_data_volume_limit
      - remaining_max_records
      - repository_id
      - repository_name
      - updated_at
    AllocationCreate:
      type: object
      description: 'Write-side serializer for provisioning a new Allocation.


        ``is_default`` is intentionally not exposed — admins who want to

        swap an owner''s default use ``POST /api/allocations/{id}/default/``

        which atomically flips the partial unique constraint.


        Optional ``parent_id`` creates a sub-Allocation carved from the named

        parent. When supplied, ``repository_id`` is ignored (the view

        inherits the parent''s repository) and the caller must own the

        parent directly. Thin-provisioning means no sum-check against the

        parent''s remaining headroom at creation — capacity is enforced at

        upload time.'
      properties:
        owner_type:
          $ref: '#/components/schemas/AllocationOwnerTypeEnum'
        owner_id:
          type: string
          format: uuid
        repository_id:
          type: string
          format: uuid
        parent_id:
          type: string
          format: uuid
          nullable: true
        data_volume_limit:
          type: integer
          minimum: 1
        max_records:
          type: integer
          minimum: 1
        alias:
          type: string
          maxLength: 255
        attach_to_asset_id:
          type: string
          format: uuid
          nullable: true
        attach_to_collection_id:
          type: string
          format: uuid
          nullable: true
      required:
      - data_volume_limit
      - max_records
    AllocationOwnerTypeEnum:
      enum:
      - project
      - user
      - organization
      type: string
      description: '* `project` - project

        * `user` - user

        * `organization` - organization'
    AllocationProject:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
      required:
      - id
      - name
    ArrowSampleJSON:
      type: object
      properties:
        rows:
          type: array
          items: {}
        columns:
          type: array
          items:
            type: string
        total:
          type: integer
        returned:
          type: integer
        offset:
          type: integer
      required:
      - columns
      - offset
      - returned
      - rows
      - total
    ArtifactRegistry:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        dataset_version:
          type: string
          format: uuid
          readOnly: true
        preprocessing_job:
          type: string
          format: uuid
          readOnly: true
        artifact_type:
          type: string
          readOnly: true
        storage_path:
          type: string
          readOnly: true
        size_bytes:
          type: integer
          readOnly: true
        checksum:
          type: string
          readOnly: true
        metadata:
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - artifact_type
      - checksum
      - created_at
      - dataset_version
      - id
      - metadata
      - preprocessing_job
      - size_bytes
      - storage_path
    Asset:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          maxLength: 255
        description:
          type: string
        alias:
          type: string
          maxLength: 255
        record_type:
          $ref: '#/components/schemas/RecordTypeEnum'
        tags:
          type: array
          items:
            type: string
            maxLength: 100
        metadata: {}
        is_locked:
          type: boolean
        owner_type:
          type: string
          readOnly: true
        owner_id:
          type: string
          format: uuid
          readOnly: true
        owner_name:
          type: string
          nullable: true
          readOnly: true
        creator_id:
          type: string
          format: uuid
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        current_content:
          oneOf:
          - $ref: '#/components/schemas/AssetContent'
          nullable: true
          readOnly: true
        creator_name:
          type: string
          nullable: true
          readOnly: true
        effective_flags:
          type: integer
          readOnly: true
        preferred_repository_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        is_migrating:
          type: boolean
          readOnly: true
        is_starred:
          type: boolean
          readOnly: true
        provenance_token:
          type: string
          nullable: true
          readOnly: true
        authors:
          type: array
          items:
            $ref: '#/components/schemas/AssetAuthor'
          readOnly: true
        image_url:
          type: string
          nullable: true
          readOnly: true
        did:
          type: string
          readOnly: true
        cited_work:
          allOf:
          - $ref: '#/components/schemas/WorkCitation'
          readOnly: true
        access_scope:
          type: string
          readOnly: true
      required:
      - access_scope
      - authors
      - created_at
      - creator_id
      - creator_name
      - current_content
      - did
      - effective_flags
      - id
      - image_url
      - is_migrating
      - is_starred
      - owner_id
      - owner_name
      - owner_type
      - preferred_repository_id
      - title
      - updated_at
    AssetAuthor:
      type: object
      description: 'Authorship credit on an Asset — distinct from Asset.creator_id.


        The ``person`` field carries a compact ``AuthorPersonSummary`` so

        callers don''t need a second round-trip to render author names.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        position:
          type: integer
          readOnly: true
        is_corresponding_author:
          type: boolean
          readOnly: true
        affiliation_snapshot:
          type: string
          readOnly: true
        person:
          allOf:
          - $ref: '#/components/schemas/AuthorPersonSummary'
          readOnly: true
      required:
      - affiliation_snapshot
      - id
      - is_corresponding_author
      - person
      - position
    AssetBucketMigration:
      type: object
      description: 'Read-only serializer for AssetBucketMigration rows.


        Includes the source and target repository ids (derived from

        allocations) so the frontend can render "Moving <asset> from A to B".

        ``asset_title`` lets the migration row present the same title +

        progress the regular Transfer rows show — "size_bytes / total"

        was already wired but the human-readable name wasn''t.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        asset_id:
          type: string
          format: uuid
          readOnly: true
        asset_title:
          type: string
          readOnly: true
        action:
          allOf:
          - $ref: '#/components/schemas/ActionEnum'
          readOnly: true
        status:
          allOf:
          - $ref: '#/components/schemas/AssetBucketMigrationStatusEnum'
          readOnly: true
        attempts:
          type: integer
          readOnly: true
        last_error:
          type: string
          readOnly: true
        source_allocation_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        target_allocation_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        source_content_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        source_repository_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        target_repository_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        source_allocation_name:
          type: string
          nullable: true
          readOnly: true
        target_allocation_name:
          type: string
          nullable: true
          readOnly: true
        initiated_by_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        started_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        completed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        bytes_total:
          type: integer
          readOnly: true
        files_total:
          type: integer
          readOnly: true
        bytes_copied:
          type: integer
          readOnly: true
        files_copied:
          type: integer
          readOnly: true
      required:
      - action
      - asset_id
      - asset_title
      - attempts
      - bytes_copied
      - bytes_total
      - completed_at
      - created_at
      - files_copied
      - files_total
      - id
      - initiated_by_id
      - last_error
      - source_allocation_id
      - source_allocation_name
      - source_content_id
      - source_repository_id
      - started_at
      - status
      - target_allocation_id
      - target_allocation_name
      - target_repository_id
      - updated_at
    AssetBucketMigrationStatusEnum:
      enum:
      - pending
      - in_progress
      - verifying
      - completing
      - completed
      - failed
      type: string
      description: '* `pending` - Pending

        * `in_progress` - In Progress

        * `verifying` - Verifying

        * `completing` - Completing

        * `completed` - Completed

        * `failed` - Failed'
    AssetContent:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        asset_id:
          type: string
          format: uuid
          readOnly: true
        allocation_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        allocation:
          allOf:
          - $ref: '#/components/schemas/ContentAllocationSummary'
          readOnly: true
          nullable: true
        storage_path:
          type: string
          readOnly: true
        size_bytes:
          type: integer
          readOnly: true
        files: {}
        status:
          allOf:
          - $ref: '#/components/schemas/AssetContentStatusEnum'
          readOnly: true
        source:
          allOf:
          - $ref: '#/components/schemas/SourceEnum'
          readOnly: true
        external_record_id:
          type: string
          readOnly: true
        external_filename:
          type: string
          readOnly: true
        external_download_url:
          type: string
          format: uri
          nullable: true
          readOnly: true
        external_download_is_landing_page:
          type: boolean
          readOnly: true
        extracted_metadata:
          readOnly: true
          nullable: true
        data_type:
          type: string
          readOnly: true
          nullable: true
        data_type_confidence:
          type: number
          format: double
          readOnly: true
          nullable: true
        extraction_status:
          allOf:
          - $ref: '#/components/schemas/ExtractionStatusEnum'
          readOnly: true
        extraction_error:
          type: string
          readOnly: true
        extraction_attempted_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - allocation
      - allocation_id
      - asset_id
      - created_at
      - data_type
      - data_type_confidence
      - external_download_is_landing_page
      - external_download_url
      - external_filename
      - external_record_id
      - extracted_metadata
      - extraction_attempted_at
      - extraction_error
      - extraction_status
      - id
      - size_bytes
      - source
      - status
      - storage_path
      - updated_at
    AssetContentStatusEnum:
      enum:
      - uploading
      - available
      - failed
      type: string
      description: '* `uploading` - Uploading

        * `available` - Available

        * `failed` - Failed'
    AssetContentWrite:
      type: object
      properties:
        files:
          type: array
          items:
            type: object
            additionalProperties: {}
          minItems: 1
        allocation_id:
          type: string
          format: uuid
          nullable: true
      required:
      - files
    AssetLocation:
      type: object
      properties:
        project:
          type: object
          nullable: true
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
          readOnly: true
        collection_path:
          type: array
          items:
            $ref: '#/components/schemas/Collection'
          readOnly: true
        page_cursor:
          type: string
          readOnly: true
          nullable: true
      required:
      - collection_path
      - page_cursor
      - project
    AssetLock:
      type: object
      properties:
        locked:
          type: boolean
      required:
      - locked
    AssetMarkdownNote:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        author:
          allOf:
          - $ref: '#/components/schemas/NoteAuthor'
          readOnly: true
        content:
          type: string
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - author
      - content
      - created_at
      - id
      - updated_at
    AssetMarkdownNoteWrite:
      type: object
      properties:
        content:
          type: string
          maxLength: 1048576
      required:
      - content
    AssetPermissionBulkMerge:
      type: object
      properties:
        asset_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
        upsert:
          type: array
          items:
            $ref: '#/components/schemas/PermissionAssignmentWrite'
        remove_subjects:
          type: array
          items:
            $ref: '#/components/schemas/RemoveSubject'
        remove_user_ids:
          type: array
          items:
            $ref: '#/components/schemas/RemoveSubject'
      required:
      - asset_ids
    AssetPermissionIntersectionRequest:
      type: object
      properties:
        asset_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
      required:
      - asset_ids
    AssetQueryRequest:
      type: object
      properties:
        query:
          type: object
          additionalProperties: {}
          description: 'Phase 1 metadata query: {"and": [<leaf>, ...]}'
        owner_type:
          $ref: '#/components/schemas/OwnerTypeEnum'
        owner_id:
          type: string
          format: uuid
        collection_id:
          type: string
          format: uuid
        record_type:
          type: array
          items:
            $ref: '#/components/schemas/RecordTypeEnum'
          description: Asset type enum values. OR logic.
        tags:
          type: array
          items:
            type: string
        locked:
          type: boolean
        q:
          type: string
          description: Text search across title, description, and alias
        search_metadata:
          type: boolean
          description: Opt in to scanning metadata values with ILIKE. Disables the GIN index — avoid on large datasets.
        id:
          type: string
          description: Asset UUID (exact) or alias (icontains)
        creator:
          type: string
          description: Creator name or email (icontains)
        scope:
          $ref: '#/components/schemas/AssetQueryScope'
      required:
      - query
    AssetQueryScope:
      type: object
      properties:
        asset_ids:
          type: array
          items:
            type: string
            format: uuid
        collection_ids:
          type: array
          items:
            type: string
            format: uuid
        project_ids:
          type: array
          items:
            type: string
            format: uuid
        allow_outside_scope:
          type: boolean
    AssetRelationship:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        type:
          allOf:
          - $ref: '#/components/schemas/AssetRelationshipTypeEnum'
          readOnly: true
        direction:
          allOf:
          - $ref: '#/components/schemas/DirectionEnum'
          readOnly: true
        related_asset:
          allOf:
          - $ref: '#/components/schemas/RelatedAssetSummary'
          readOnly: true
        analysis_mode:
          readOnly: true
          nullable: true
          oneOf:
          - $ref: '#/components/schemas/AssetRelationshipAnalysisModeEnum'
          - $ref: '#/components/schemas/NullEnum'
        qualifier_note:
          type: string
          readOnly: true
      required:
      - analysis_mode
      - direction
      - id
      - qualifier_note
      - related_asset
      - type
    AssetRelationshipAnalysisModeEnum:
      enum:
      - non_destructive
      - altering
      - destructive
      - in_situ
      - ex_situ
      - invasive
      - non_invasive
      type: string
      description: '* `non_destructive` - Non-destructive

        * `altering` - Altering

        * `destructive` - Destructive

        * `in_situ` - In-situ

        * `ex_situ` - Ex-situ

        * `invasive` - Invasive

        * `non_invasive` - Non-invasive'
    AssetRelationshipTypeEnum:
      enum:
      - analysis_of
      - part_of
      - instrument_used_to
      - created_sample
      - derived_from
      - measured_by
      - calibrated_with
      - prepared_from
      - sampled_from
      - aliquot_of
      - supersedes
      - revision_of
      - conforms_to
      - annotated_with
      - validated_by
      - controls_for
      - baseline_for
      - trained_on
      - parameterized_by
      - implements
      - cited_by
      - cites
      - applied_to
      - assigns_perturbation_to
      - boiled_into
      - builds_library
      - carbonated_into
      - checkpoint_of
      - clarified_into
      - conditioned_into
      - config_for
      - converts
      - cooled_into
      - creator
      - data_from
      - derives_neighborhoods_from
      - feeds_into
      - fermented_into
      - figure_from
      - funded_by
      - harvested_as
      - informs_design
      - integrates
      - lautered_into
      - maps_into_spatial_context
      - mashed_into
      - milled_into
      - models_effect_on
      - packaged_into
      - pitched_into
      - prepared_library_from
      - prioritizes
      - processed_into
      - produces
      - produces_material
      - produces_record
      - qc_of
      - qualified_by
      - records_qc
      - records_telemetry
      - released_as
      - released_for
      - sample_produced_by
      - sequenced_as
      - specified_by
      - split_into
      - step_of
      - synthesizes
      - treated_into
      - trends
      - used_for_training
      type: string
      description: '* `analysis_of` - Analysis Of

        * `part_of` - Part Of

        * `instrument_used_to` - Instrument Used To

        * `created_sample` - Created Sample

        * `derived_from` - Derived From

        * `measured_by` - Measured By

        * `calibrated_with` - Calibrated With

        * `prepared_from` - Prepared From

        * `sampled_from` - Sampled From

        * `aliquot_of` - Aliquot Of

        * `supersedes` - Supersedes

        * `revision_of` - Revision Of

        * `conforms_to` - Conforms To

        * `annotated_with` - Annotated With

        * `validated_by` - Validated By

        * `controls_for` - Controls For

        * `baseline_for` - Baseline For

        * `trained_on` - Trained On

        * `parameterized_by` - Parameterized By

        * `implements` - Implements

        * `cited_by` - Cited By

        * `cites` - Cites

        * `applied_to` - Applied To

        * `assigns_perturbation_to` - Assigns Perturbation To

        * `boiled_into` - Boiled Into

        * `builds_library` - Builds Library

        * `carbonated_into` - Carbonated Into

        * `checkpoint_of` - Checkpoint Of

        * `clarified_into` - Clarified Into

        * `conditioned_into` - Conditioned Into

        * `config_for` - Config For

        * `converts` - Converts

        * `cooled_into` - Cooled Into

        * `creator` - Creator

        * `data_from` - Data From

        * `derives_neighborhoods_from` - Derives Neighborhoods From

        * `feeds_into` - Feeds Into

        * `fermented_into` - Fermented Into

        * `figure_from` - Figure From

        * `funded_by` - Funded By

        * `harvested_as` - Harvested As

        * `informs_design` - Informs Design

        * `integrates` - Integrates

        * `lautered_into` - Lautered Into

        * `maps_into_spatial_context` - Maps Into Spatial Context

        * `mashed_into` - Mashed Into

        * `milled_into` - Milled Into

        * `models_effect_on` - Models Effect On

        * `packaged_into` - Packaged Into

        * `pitched_into` - Pitched Into

        * `prepared_library_from` - Prepared Library From

        * `prioritizes` - Prioritizes

        * `processed_into` - Processed Into

        * `produces` - Produces

        * `produces_material` - Produces Material

        * `produces_record` - Produces Record

        * `qc_of` - QC Of

        * `qualified_by` - Qualified By

        * `records_qc` - Records QC

        * `records_telemetry` - Records Telemetry

        * `released_as` - Released As

        * `released_for` - Released For

        * `sample_produced_by` - Sample Produced By

        * `sequenced_as` - Sequenced As

        * `specified_by` - Specified By

        * `split_into` - Split Into

        * `step_of` - Step Of

        * `synthesizes` - Synthesizes

        * `treated_into` - Treated Into

        * `trends` - Trends

        * `used_for_training` - Used For Training'
    AssetRelationshipWrite:
      type: object
      description: 'Create payload for ``POST /api/assets/{id}/relationships/``.


        The source (``from_asset``) is the path asset; ``to_asset_id`` is the

        target. ``analysis_mode`` is one of the model''s choices (or blank/null).'
      properties:
        to_asset_id:
          type: string
          format: uuid
        type:
          type: string
          maxLength: 255
        analysis_mode:
          nullable: true
          oneOf:
          - $ref: '#/components/schemas/AssetRelationshipAnalysisModeEnum'
          - $ref: '#/components/schemas/BlankEnum'
          - $ref: '#/components/schemas/NullEnum'
        qualifier_time:
          type: string
          format: date-time
          nullable: true
        qualifier_note:
          type: string
          default: ''
          maxLength: 5000
        qualifiers: {}
      required:
      - to_asset_id
      - type
    AssetSearch:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          maxLength: 255
        description:
          type: string
        alias:
          type: string
          maxLength: 255
        record_type:
          $ref: '#/components/schemas/RecordTypeEnum'
        tags:
          type: array
          items:
            type: string
            maxLength: 100
        metadata: {}
        is_locked:
          type: boolean
        owner_type:
          type: string
          readOnly: true
        owner_id:
          type: string
          format: uuid
          readOnly: true
        owner_name:
          type: string
          nullable: true
          readOnly: true
        creator_id:
          type: string
          format: uuid
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        current_content:
          oneOf:
          - $ref: '#/components/schemas/AssetContent'
          nullable: true
          readOnly: true
        creator_name:
          type: string
          nullable: true
          readOnly: true
        effective_flags:
          type: integer
          readOnly: true
        preferred_repository_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        is_migrating:
          type: boolean
          readOnly: true
        is_starred:
          type: boolean
          readOnly: true
        provenance_token:
          type: string
          nullable: true
          readOnly: true
        authors:
          type: array
          items:
            $ref: '#/components/schemas/AssetAuthor'
          readOnly: true
        image_url:
          type: string
          nullable: true
          readOnly: true
        did:
          type: string
          readOnly: true
        cited_work:
          allOf:
          - $ref: '#/components/schemas/WorkCitation'
          readOnly: true
        access_scope:
          type: string
          readOnly: true
      required:
      - access_scope
      - authors
      - created_at
      - creator_id
      - creator_name
      - current_content
      - did
      - effective_flags
      - id
      - image_url
      - is_migrating
      - is_starred
      - owner_id
      - owner_name
      - owner_type
      - preferred_repository_id
      - title
      - updated_at
    AssetWrite:
      type: object
      properties:
        title:
          type: string
          maxLength: 255
        description:
          type: string
          default: ''
        alias:
          type: string
          default: ''
          maxLength: 255
        record_type:
          $ref: '#/components/schemas/RecordTypeEnum'
        tags:
          type: array
          items:
            type: string
            maxLength: 100
        metadata: {}
        owner_type:
          $ref: '#/components/schemas/OwnerTypeEnum'
        owner_id:
          type: string
          format: uuid
        collection_id:
          type: string
          format: uuid
          nullable: true
        allocation_id:
          type: string
          format: uuid
          nullable: true
        preferred_repository_id:
          type: string
          format: uuid
          nullable: true
        license:
          type: string
      required:
      - owner_id
      - owner_type
      - title
    AuthorPersonSummary:
      type: object
      description: 'Compact person summary embedded in asset-author entries.


        Carries just enough (``id``, ``full_name``, ``orcid_id``) to render

        an author credit without a follow-up lookup.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        full_name:
          type: string
          readOnly: true
        orcid_id:
          type: string
          readOnly: true
      required:
      - full_name
      - id
      - orcid_id
    AvatarVariantEnum:
      enum:
      - orbit
      - beam
      - spark
      - pixel
      - halo
      - ribbon
      - stack
      - wave
      - prism
      - nova
      - dash
      - corner
      - sunrise
      - signal
      - capsule
      - arc
      - gem
      - mesh
      - comet
      - portal
      type: string
      description: '* `orbit` - Orbit

        * `beam` - Beam

        * `spark` - Spark

        * `pixel` - Pixel

        * `halo` - Halo

        * `ribbon` - Ribbon

        * `stack` - Stack

        * `wave` - Wave

        * `prism` - Prism

        * `nova` - Nova

        * `dash` - Dash

        * `corner` - Corner

        * `sunrise` - Sunrise

        * `signal` - Signal

        * `capsule` - Capsule

        * `arc` - Arc

        * `gem` - Gem

        * `mesh` - Mesh

        * `comet` - Comet

        * `portal` - Portal'
    BibliometricFormatEnum:
      enum:
      - bibtex
      - ris
      - apa
      - mla
      - chicago
      type: string
      description: '* `bibtex` - BibTeX

        * `ris` - RIS

        * `apa` - APA

        * `mla` - MLA

        * `chicago` - Chicago'
    BlankEnum:
      enum:
      - ''
    Collection:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          maxLength: 255
        description:
          type: string
        alias:
          type: string
          maxLength: 255
        tags:
          type: array
          items:
            type: string
            maxLength: 100
        type:
          type: array
          items:
            type: string
            maxLength: 100
        parent_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        parent_ids:
          type: array
          items:
            type: string
            format: uuid
          readOnly: true
        owner_user_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        owner_project_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        is_root:
          type: boolean
          readOnly: true
        preferred_repository_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        owner_user_name:
          type: string
          nullable: true
          readOnly: true
        owner_project_name:
          type: string
          readOnly: true
          nullable: true
        effective_flags:
          type: integer
          readOnly: true
        is_starred:
          type: boolean
          readOnly: true
        provenance_token:
          type: string
          nullable: true
          readOnly: true
        access_scope:
          type: string
          readOnly: true
      required:
      - access_scope
      - created_at
      - effective_flags
      - id
      - is_root
      - is_starred
      - owner_project_id
      - owner_project_name
      - owner_user_id
      - owner_user_name
      - parent_id
      - parent_ids
      - preferred_repository_id
      - title
      - updated_at
    CollectionAssetsAddRequest:
      type: object
      properties:
        asset_id:
          type: string
          format: uuid
      required:
      - asset_id
    CollectionBreadcrumbPathSegment:
      type: object
      properties:
        kind:
          $ref: '#/components/schemas/CollectionBreadcrumbPathSegmentKindEnum'
        id:
          type: string
          format: uuid
        label:
          type: string
        accessible:
          type: boolean
        project_id:
          type: string
          format: uuid
          nullable: true
        collection_ids:
          type: array
          items:
            type: string
            format: uuid
      required:
      - accessible
      - collection_ids
      - id
      - kind
      - label
      - project_id
    CollectionBreadcrumbPathSegmentKindEnum:
      enum:
      - project
      - collection
      type: string
      description: '* `project` - project

        * `collection` - collection'
    CollectionEdgesAddRequest:
      type: object
      properties:
        items:
          type: array
          items: {}
      required:
      - items
    CollectionNote:
      type: object
      properties:
        note:
          $ref: '#/components/schemas/Note'
        asset:
          $ref: '#/components/schemas/Asset'
        path:
          type: array
          items:
            $ref: '#/components/schemas/PathSegment'
        collection_path:
          type: array
          items:
            $ref: '#/components/schemas/Collection'
      required:
      - asset
      - collection_path
      - note
      - path
    CollectionWrite:
      type: object
      properties:
        title:
          type: string
          maxLength: 255
        description:
          type: string
          default: ''
        alias:
          type: string
          default: ''
          maxLength: 255
        tags:
          type: array
          items:
            type: string
            maxLength: 100
        type:
          type: array
          items:
            type: string
            maxLength: 100
        parent_id:
          type: string
          format: uuid
          nullable: true
        owner_type:
          $ref: '#/components/schemas/OwnerTypeEnum'
        owner_id:
          type: string
          format: uuid
        preferred_repository_id:
          type: string
          format: uuid
          nullable: true
        license:
          type: string
    ContentAllocationSummary:
      type: object
      description: Compact allocation projection embedded inside AssetContentSerializer.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        alias:
          type: string
          readOnly: true
        repository_name:
          type: string
          readOnly: true
        is_default:
          type: boolean
          readOnly: true
        current_bytes:
          type: integer
          readOnly: true
        data_volume_limit:
          type: integer
          readOnly: true
        current_record_count:
          type: integer
          readOnly: true
        max_records:
          type: integer
          readOnly: true
      required:
      - alias
      - current_bytes
      - current_record_count
      - data_volume_limit
      - id
      - is_default
      - max_records
      - repository_name
    Dataset:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        description:
          type: string
        owner_user:
          type: string
          format: uuid
          nullable: true
        owner_project:
          type: string
          format: uuid
          nullable: true
        creator:
          type: string
          format: uuid
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        versions:
          type: array
          items:
            $ref: '#/components/schemas/DatasetVersion'
          readOnly: true
        did:
          type: string
          readOnly: true
      required:
      - created_at
      - creator
      - did
      - id
      - name
      - updated_at
      - versions
    DatasetCreate:
      type: object
      description: 'POST /datasets/ — create a Dataset and its first DatasetVersion

        from an existing AssetContent.


        The Dataset is owned by the caller by default. Pass

        ``owner_project_id`` to create a project-owned Dataset instead

        (the caller must be a member of that project); the view enforces

        ownership and resolves the user owner implicitly.'
      properties:
        name:
          type: string
          maxLength: 255
        description:
          type: string
          default: ''
          maxLength: 4096
        asset_content_id:
          type: string
          format: uuid
        owner_project_id:
          type: string
          format: uuid
          nullable: true
      required:
      - asset_content_id
      - name
    DatasetError:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        preprocessing_job:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        error_code:
          type: string
          readOnly: true
        error_message:
          type: string
          readOnly: true
        error_context:
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - error_code
      - error_context
      - error_message
      - id
      - preprocessing_job
    DatasetVersion:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        dataset:
          type: string
          format: uuid
          readOnly: true
        version_number:
          type: integer
          readOnly: true
        asset_content:
          type: string
          format: uuid
          readOnly: true
        status:
          allOf:
          - $ref: '#/components/schemas/DatasetVersionStatusEnum'
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - asset_content
      - created_at
      - dataset
      - id
      - status
      - updated_at
      - version_number
    DatasetVersionCreate:
      type: object
      description: POST /datasets/{id}/versions/ — append a new DatasetVersion.
      properties:
        asset_content_id:
          type: string
          format: uuid
      required:
      - asset_content_id
    DatasetVersionStatus:
      type: object
      description: GET /datasets/{id}/versions/{vid}/status response shape.
      properties:
        status:
          $ref: '#/components/schemas/DatasetVersionStatusEnum'
        latest_job:
          allOf:
          - $ref: '#/components/schemas/PreprocessingJob'
          nullable: true
        errors:
          type: array
          items:
            $ref: '#/components/schemas/DatasetError'
        error_count:
          type: integer
        errors_truncated:
          type: boolean
      required:
      - error_count
      - errors
      - errors_truncated
      - latest_job
      - status
    DatasetVersionStatusEnum:
      enum:
      - UPLOADED
      - PREPROCESSING_QUEUED
      - PREPROCESSING_RUNNING
      - PREPROCESSING_FAILED
      - READY
      - DEPRECATED
      type: string
      description: '* `UPLOADED` - Uploaded

        * `PREPROCESSING_QUEUED` - Preprocessing Queued

        * `PREPROCESSING_RUNNING` - Preprocessing Running

        * `PREPROCESSING_FAILED` - Preprocessing Failed

        * `READY` - Ready

        * `DEPRECATED` - Deprecated'
    DirectionEnum:
      enum:
      - incoming
      - outgoing
      type: string
      description: '* `incoming` - incoming

        * `outgoing` - outgoing'
    ExecutorEnum:
      enum:
      - browser
      - client
      type: string
      description: '* `browser` - Browser

        * `client` - Client (SDK endpoint)'
    ExtractionStatusEnum:
      enum:
      - pending
      - succeeded
      - skipped
      - failed
      type: string
      description: '* `pending` - Pending

        * `succeeded` - Succeeded

        * `skipped` - Skipped

        * `failed` - Failed'
    FundingAgency:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        abbreviation:
          type: string
          maxLength: 64
        url:
          type: string
          format: uri
          maxLength: 500
        openalex_id:
          type: string
          maxLength: 64
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - id
      - name
    FundingAgencyMinimal:
      type: object
      description: 'Minimal funding-agency reference: ``id`` plus display fields

        (``name``, ``abbreviation``).'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        abbreviation:
          type: string
          maxLength: 64
      required:
      - id
      - name
    GeoBoundCountrySet:
      type: object
      description: 'Versioned country-code preset used by project geobound policies

        (DSS-650). A shared global reference table: readable by any

        authenticated user (so they can pick a set) but mutated only by system

        admins (see GeoBoundCountrySet*View). ``kind`` is auto-derived as a

        ChoiceField from the model choices, so an invalid kind 400s.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        slug:
          type: string
          maxLength: 96
          pattern: ^[-a-zA-Z0-9_]+$
        name:
          type: string
          maxLength: 255
        description:
          type: string
        country_codes:
          type: array
          items:
            type: string
        kind:
          $ref: '#/components/schemas/GeoBoundCountrySetKindEnum'
        source_name:
          type: string
          maxLength: 255
        source_url:
          type: string
          format: uri
          maxLength: 200
        source_version:
          type: string
          maxLength: 128
        is_system:
          type: boolean
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - id
      - name
      - slug
      - updated_at
    GeoBoundCountrySetKindEnum:
      enum:
      - allow
      - deny
      type: string
      description: '* `allow` - Allowlist (permit only these countries)

        * `deny` - Denylist (block these countries)'
    GeoboundBasisEnum:
      enum:
      - ip
      - affiliation
      - ip_or_affiliation
      - ip_and_affiliation
      type: string
      description: '* `ip` - IP country

        * `affiliation` - Affiliation country

        * `ip_or_affiliation` - IP or affiliation country

        * `ip_and_affiliation` - IP and affiliation country'
    GrantRead:
      type: object
      description: 'Full read shape; nested funding_agency for client convenience.


        Excludes `search_vector` (binary tsvector — not safe to JSON-serialize).'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        project:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        funding_agency:
          allOf:
          - $ref: '#/components/schemas/FundingAgencyMinimal'
          readOnly: true
        grant_id:
          type: string
          readOnly: true
        registry_source:
          type: string
          readOnly: true
        title:
          type: string
          readOnly: true
        abstract:
          type: string
          readOnly: true
          description: Short structured summary, registry-supplied (e.g. NIH abstract).
        description:
          type: string
          readOnly: true
          description: Long-form public health relevance / lay description.
        funding_amount:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          readOnly: true
          nullable: true
        currency:
          type: string
          readOnly: true
        direct_cost_amt:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          readOnly: true
          nullable: true
        indirect_cost_amt:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          readOnly: true
          nullable: true
        award_amount:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          readOnly: true
          nullable: true
        funding_mechanism:
          type: string
          readOnly: true
        award_type:
          type: string
          readOnly: true
        activity_code:
          type: string
          readOnly: true
        start_date:
          type: string
          format: date
          readOnly: true
          nullable: true
        end_date:
          type: string
          format: date
          readOnly: true
          nullable: true
        fiscal_year:
          type: integer
          readOnly: true
          nullable: true
        url:
          type: string
          format: uri
          readOnly: true
        project_detail_url:
          type: string
          format: uri
          readOnly: true
        extracted_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        raw_data:
          readOnly: true
        appl_id:
          type: integer
          readOnly: true
          nullable: true
        subproject_id:
          type: string
          readOnly: true
        project_num:
          type: string
          readOnly: true
        project_serial_num:
          type: string
          readOnly: true
        core_project_num:
          type: string
          readOnly: true
        project_activity_code:
          type: string
          readOnly: true
        project_suffix_code:
          type: string
          readOnly: true
        mechanism_code_dc:
          type: string
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
        is_new:
          type: boolean
          readOnly: true
        contact_pi_name:
          type: string
          readOnly: true
        agency_ic_admin_code:
          type: string
          readOnly: true
        agency_ic_admin_name:
          type: string
          readOnly: true
        agency_ic_admin_abbrev:
          type: string
          readOnly: true
        cong_dist:
          type: string
          readOnly: true
        geo_lat:
          type: number
          format: double
          readOnly: true
          nullable: true
        geo_lon:
          type: number
          format: double
          readOnly: true
          nullable: true
        spending_category:
          type: string
          readOnly: true
        spending_subcategory:
          type: string
          readOnly: true
        spending_categories_desc:
          type: string
          readOnly: true
        terms:
          type: string
          readOnly: true
        pref_terms:
          type: string
          readOnly: true
        phr_text:
          type: string
          readOnly: true
        covid_response:
          type: string
          readOnly: true
        arra_funded:
          type: string
          readOnly: true
        cfda_code:
          type: string
          readOnly: true
        openalex_id:
          type: string
          readOnly: true
        provenance:
          type: string
          readOnly: true
        funded_outputs_count:
          type: integer
          readOnly: true
          nullable: true
        custom_fields:
          readOnly: true
        version_rev:
          type: integer
          readOnly: true
        is_latest:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - abstract
      - activity_code
      - agency_ic_admin_abbrev
      - agency_ic_admin_code
      - agency_ic_admin_name
      - appl_id
      - arra_funded
      - award_amount
      - award_type
      - cfda_code
      - cong_dist
      - contact_pi_name
      - core_project_num
      - covid_response
      - created_at
      - currency
      - custom_fields
      - description
      - direct_cost_amt
      - end_date
      - extracted_at
      - fiscal_year
      - funded_outputs_count
      - funding_agency
      - funding_amount
      - funding_mechanism
      - geo_lat
      - geo_lon
      - grant_id
      - id
      - indirect_cost_amt
      - is_active
      - is_latest
      - is_new
      - mechanism_code_dc
      - openalex_id
      - phr_text
      - pref_terms
      - project
      - project_activity_code
      - project_detail_url
      - project_num
      - project_serial_num
      - project_suffix_code
      - provenance
      - raw_data
      - registry_source
      - spending_categories_desc
      - spending_category
      - spending_subcategory
      - start_date
      - subproject_id
      - terms
      - title
      - url
      - version_rev
    GrantWrite:
      type: object
      description: 'User-editable subset.


        Ingest-pipeline-owned fields (raw_data, extracted_at, provenance,

        version_rev, is_latest, is_new, search_vector, funded_outputs_count)

        are NOT user-editable — they belong to the ingest layer.'
      properties:
        project:
          type: string
          format: uuid
          nullable: true
        funding_agency:
          type: string
          format: uuid
          nullable: true
        grant_id:
          type: string
          maxLength: 255
        registry_source:
          type: string
          maxLength: 64
        title:
          type: string
          maxLength: 1024
        abstract:
          type: string
          description: Short structured summary, registry-supplied (e.g. NIH abstract).
        description:
          type: string
          description: Long-form public health relevance / lay description.
        funding_amount:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          nullable: true
        currency:
          type: string
          maxLength: 16
        direct_cost_amt:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          nullable: true
        indirect_cost_amt:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          nullable: true
        award_amount:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          nullable: true
        funding_mechanism:
          type: string
          maxLength: 255
        award_type:
          type: string
          maxLength: 255
        activity_code:
          type: string
          maxLength: 64
        start_date:
          type: string
          format: date
          nullable: true
        end_date:
          type: string
          format: date
          nullable: true
        fiscal_year:
          type: integer
          maximum: 9223372036854775807
          minimum: -9223372036854775808
          format: int64
          nullable: true
        url:
          type: string
          format: uri
          maxLength: 200
        project_detail_url:
          type: string
          format: uri
          maxLength: 200
        appl_id:
          type: integer
          maximum: 9223372036854775807
          minimum: -9223372036854775808
          format: int64
          nullable: true
        subproject_id:
          type: string
          maxLength: 255
        project_num:
          type: string
          maxLength: 255
        project_serial_num:
          type: string
          maxLength: 255
        core_project_num:
          type: string
          maxLength: 255
        project_activity_code:
          type: string
          maxLength: 64
        project_suffix_code:
          type: string
          maxLength: 64
        mechanism_code_dc:
          type: string
          maxLength: 64
        is_active:
          type: boolean
        contact_pi_name:
          type: string
          maxLength: 255
        agency_ic_admin_code:
          type: string
          maxLength: 64
        agency_ic_admin_name:
          type: string
          maxLength: 255
        agency_ic_admin_abbrev:
          type: string
          maxLength: 64
        cong_dist:
          type: string
          maxLength: 64
        geo_lat:
          type: number
          format: double
          nullable: true
        geo_lon:
          type: number
          format: double
          nullable: true
        spending_category:
          type: string
          maxLength: 255
        spending_subcategory:
          type: string
          maxLength: 255
        spending_categories_desc:
          type: string
        terms:
          type: string
        pref_terms:
          type: string
        phr_text:
          type: string
        covid_response:
          type: string
          maxLength: 255
        arra_funded:
          type: string
          maxLength: 255
        cfda_code:
          type: string
          maxLength: 128
        openalex_id:
          type: string
          maxLength: 64
        custom_fields: {}
      required:
      - grant_id
      - registry_source
      - title
    Group:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        organization_id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        description:
          type: string
          readOnly: true
        type:
          allOf:
          - $ref: '#/components/schemas/GroupTypeEnum'
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        member_count:
          type: integer
          readOnly: true
      required:
      - created_at
      - description
      - id
      - member_count
      - name
      - organization_id
      - type
      - updated_at
    GroupAssignment:
      type: object
      properties:
        object_type:
          $ref: '#/components/schemas/PermissionObjectTypeEnum'
        object_id:
          type: string
          format: uuid
        display_name:
          type: string
        flags:
          type: integer
          minimum: 1
      required:
      - display_name
      - flags
      - object_id
      - object_type
    GroupMember:
      type: object
      properties:
        user:
          allOf:
          - $ref: '#/components/schemas/GroupMemberUser'
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - user
    GroupMemberAdd:
      type: object
      properties:
        user_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
      required:
      - user_ids
    GroupMemberUser:
      type: object
      description: 'Resolve ``user.person`` once per serialization pass.


        ``user.person`` memoizes per instance, but distinct users in a list are

        distinct instances — so a list serializer would still issue one

        ``Person`` query per row. When used ``many=True`` this mixin routes

        through :class:`_PersonReadThroughListSerializer`, which calls

        ``User.attach_persons`` to batch the whole page into a single query;

        the per-render ``context`` cache below then dedups the name+email

        double-read for each user.


        The context cache lives only for the lifetime of the serializer tree,

        so one ``.data`` render resolves each distinct user''s ``Person`` at

        most once and re-batches fresh on the next render.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        email:
          type: string
          readOnly: true
        name:
          type: string
          readOnly: true
      required:
      - email
      - id
      - name
    GroupTypeEnum:
      enum:
      - members
      - custom
      type: string
      description: '* `members` - Members

        * `custom` - Custom'
    GroupWrite:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
        description:
          type: string
          default: ''
        organization_id:
          type: string
          format: uuid
      required:
      - name
      - organization_id
    LlmProviderTierPreferenceEnum:
      enum:
      - zdr
      - private_endpoint
      type: string
      description: '* `zdr` - ZDR (Zero Data Retention)

        * `private_endpoint` - Private Endpoint'
    Me:
      type: object
      description: 'Resolve ``user.person`` once per serialization pass.


        ``user.person`` memoizes per instance, but distinct users in a list are

        distinct instances — so a list serializer would still issue one

        ``Person`` query per row. When used ``many=True`` this mixin routes

        through :class:`_PersonReadThroughListSerializer`, which calls

        ``User.attach_persons`` to batch the whole page into a single query;

        the per-render ``context`` cache below then dedups the name+email

        double-read for each user.


        The context cache lives only for the lifetime of the serializer tree,

        so one ``.data`` render resolves each distinct user''s ``Person`` at

        most once and re-batches fresh on the next render.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        email:
          type: string
          readOnly: true
        name:
          type: string
          readOnly: true
        is_system_admin:
          type: boolean
          readOnly: true
        is_repository_admin:
          type: boolean
          readOnly: true
        person_id:
          type: string
          format: uuid
          readOnly: true
        visible_outside_org:
          type: boolean
          readOnly: true
        email_pending_verification:
          type: string
          nullable: true
          readOnly: true
        root_collection_id:
          type: string
          format: uuid
          readOnly: true
        sole_organization_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        admin_organizations:
          type: array
          items:
            $ref: '#/components/schemas/Organization'
          readOnly: true
        memberships:
          type: array
          items:
            $ref: '#/components/schemas/OrganizationMembership'
          readOnly: true
        avatar_url:
          type: string
          nullable: true
          readOnly: true
        avatar_variant:
          allOf:
          - $ref: '#/components/schemas/AvatarVariantEnum'
          readOnly: true
        avatar_color:
          type: string
          readOnly: true
        custom_ollama_url:
          type: string
          readOnly: true
        custom_ollama_model:
          type: string
          readOnly: true
        custom_clip_service_url:
          type: string
          readOnly: true
        has_custom_clip_service_token:
          type: boolean
          readOnly: true
        ai_search_enabled:
          type: boolean
          readOnly: true
        embeddings_enabled:
          type: boolean
          readOnly: true
        default_project_geobound_enabled:
          type: boolean
          readOnly: true
        default_project_geobound_basis:
          allOf:
          - $ref: '#/components/schemas/GeoboundBasisEnum'
          readOnly: true
        default_project_geobound_allowed_countries:
          type: array
          items:
            type: string
            pattern: ^[A-Z]{2}$
            maxLength: 2
          readOnly: true
        default_project_geobound_allowed_country_set:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        default_project_geobound_denied_country_set:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        default_project_geobound_block_vpn:
          type: boolean
          readOnly: true
        default_project_geobound_fail_closed:
          type: boolean
          readOnly: true
        collection_projection_enabled:
          type: boolean
          readOnly: true
        default_bibliometric_format:
          allOf:
          - $ref: '#/components/schemas/BibliometricFormatEnum'
          readOnly: true
      required:
      - admin_organizations
      - ai_search_enabled
      - avatar_color
      - avatar_url
      - avatar_variant
      - collection_projection_enabled
      - custom_clip_service_url
      - custom_ollama_model
      - custom_ollama_url
      - default_bibliometric_format
      - default_project_geobound_allowed_countries
      - default_project_geobound_allowed_country_set
      - default_project_geobound_basis
      - default_project_geobound_block_vpn
      - default_project_geobound_denied_country_set
      - default_project_geobound_enabled
      - default_project_geobound_fail_closed
      - email
      - email_pending_verification
      - embeddings_enabled
      - has_custom_clip_service_token
      - id
      - is_repository_admin
      - is_system_admin
      - memberships
      - name
      - person_id
      - root_collection_id
      - sole_organization_id
      - visible_outside_org
    MetadataPreviewStatusEnum:
      enum:
      - succeeded
      - skipped
      - failed
      type: string
      description: '* `succeeded` - Succeeded

        * `skipped` - Skipped

        * `failed` - Failed'
    Note:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        author:
          allOf:
          - $ref: '#/components/schemas/NoteAuthor'
          readOnly: true
        content:
          type: string
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        replies:
          type: array
          items:
            $ref: '#/components/schemas/Reply'
          readOnly: true
      required:
      - author
      - content
      - created_at
      - id
      - replies
    NoteAuthor:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        email:
          type: string
          format: email
          readOnly: true
      required:
      - email
      - id
      - name
    NoteWrite:
      type: object
      properties:
        content:
          type: string
        parent_id:
          type: string
          format: uuid
          nullable: true
      required:
      - content
    NullEnum:
      enum:
      - null
    OrgMemberRoleEnum:
      enum:
      - member
      - admin
      type: string
      description: '* `member` - Member

        * `admin` - Admin'
    Organization:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        description:
          type: string
        whitelisted_email_domains:
          type: array
          items:
            type: string
            maxLength: 255
        globus_identity_provider_id:
          type: string
          format: uuid
          nullable: true
          description: Globus institutional IdP UUID for auto-join on SSO signup.
        allow_external_ai:
          type: boolean
        allow_user_agent_config:
          type: boolean
        llm_provider_tier_preference:
          $ref: '#/components/schemas/LlmProviderTierPreferenceEnum'
        custom_ollama_url:
          type: string
          maxLength: 255
        custom_ollama_model:
          type: string
          maxLength: 128
        custom_clip_service_url:
          type: string
          maxLength: 255
        has_custom_clip_service_token:
          type: boolean
          readOnly: true
        default_repository_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        default_project_geobound_configured:
          type: boolean
        default_project_geobound_enabled:
          type: boolean
        default_project_geobound_basis:
          $ref: '#/components/schemas/GeoboundBasisEnum'
        default_project_geobound_allowed_countries:
          type: array
          items:
            type: string
            pattern: ^[A-Z]{2}$
            maxLength: 2
        default_project_geobound_allowed_country_set:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_denied_country_set:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_block_vpn:
          type: boolean
        default_project_geobound_fail_closed:
          type: boolean
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        member_count:
          type: integer
          readOnly: true
          default: 0
      required:
      - created_at
      - default_repository_id
      - has_custom_clip_service_token
      - id
      - member_count
      - name
      - updated_at
    OrganizationMember:
      type: object
      description: Read-only membership row shown inside org member lists.
      properties:
        id:
          type: integer
          readOnly: true
        user:
          allOf:
          - $ref: '#/components/schemas/UserSearch'
          readOnly: true
        role:
          allOf:
          - $ref: '#/components/schemas/OrgMemberRoleEnum'
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - id
      - role
      - user
    OrganizationMemberWrite:
      type: object
      description: Used for POST (add member) and PATCH (change role).
      properties:
        user_id:
          type: string
          format: uuid
        role:
          $ref: '#/components/schemas/OrgMemberRoleEnum'
      required:
      - role
      - user_id
    OrganizationMembership:
      type: object
      description: 'Summary of a user''s organization membership: the organization

        (``id`` + ``name``) and the user''s role in it.'
      properties:
        organization:
          allOf:
          - $ref: '#/components/schemas/_SlimOrg'
          readOnly: true
        role:
          allOf:
          - $ref: '#/components/schemas/OrgMemberRoleEnum'
          readOnly: true
      required:
      - organization
      - role
    OrganizationWrite:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
        description:
          type: string
        whitelisted_email_domains:
          type: array
          items:
            type: string
            maxLength: 255
        globus_identity_provider_id:
          type: string
          format: uuid
          nullable: true
          description: Globus institutional IdP UUID for auto-join on SSO signup.
        allow_external_ai:
          type: boolean
        allow_user_agent_config:
          type: boolean
        llm_provider_tier_preference:
          $ref: '#/components/schemas/LlmProviderTierPreferenceEnum'
        custom_ollama_url:
          type: string
          maxLength: 255
        custom_ollama_model:
          type: string
          maxLength: 128
        custom_clip_service_url:
          type: string
          maxLength: 255
        custom_clip_service_token:
          type: string
          writeOnly: true
          maxLength: 4096
        default_repository_id:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_configured:
          type: boolean
        default_project_geobound_enabled:
          type: boolean
        default_project_geobound_basis:
          $ref: '#/components/schemas/GeoboundBasisEnum'
        default_project_geobound_allowed_countries:
          type: array
          items:
            type: string
        default_project_geobound_allowed_country_set:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_denied_country_set:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_block_vpn:
          type: boolean
        default_project_geobound_fail_closed:
          type: boolean
      required:
      - name
    OwnerTypeEnum:
      enum:
      - project
      - user
      type: string
      description: '* `project` - project

        * `user` - user'
    PaginatedAdminUserList:
      type: object
      properties:
        count:
          type: integer
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/AdminUserList'
      required:
      - count
      - next
      - previous
      - results
    PaginatedTransferResponse:
      type: object
      properties:
        count:
          type: integer
        next:
          type: string
          nullable: true
        previous:
          type: string
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/Transfer'
      required:
      - count
      - next
      - previous
      - results
    PatchedAdminUserOrgRole:
      type: object
      properties:
        role:
          $ref: '#/components/schemas/OrgMemberRoleEnum'
    PatchedAdminUserPatch:
      type: object
      description: 'Only the two privilege flags are mutable through this surface; every

        other user field stays out of reach of sysadmin user-management.'
      properties:
        is_active:
          type: boolean
        is_system_admin:
          type: boolean
    PatchedAllocationLimit:
      type: object
      properties:
        data_volume_limit:
          type: integer
          minimum: 0
        max_records:
          type: integer
          minimum: 0
        alias:
          type: string
          maxLength: 255
    PatchedAssetPatch:
      type: object
      properties:
        title:
          type: string
          maxLength: 255
        description:
          type: string
        alias:
          type: string
          maxLength: 255
        record_type:
          $ref: '#/components/schemas/RecordTypeEnum'
        tags:
          type: array
          items:
            type: string
            maxLength: 100
        metadata: {}
        preferred_repository_id:
          type: string
          format: uuid
          nullable: true
    PatchedCollectionWrite:
      type: object
      properties:
        title:
          type: string
          maxLength: 255
        description:
          type: string
          default: ''
        alias:
          type: string
          default: ''
          maxLength: 255
        tags:
          type: array
          items:
            type: string
            maxLength: 100
        type:
          type: array
          items:
            type: string
            maxLength: 100
        parent_id:
          type: string
          format: uuid
          nullable: true
        owner_type:
          $ref: '#/components/schemas/OwnerTypeEnum'
        owner_id:
          type: string
          format: uuid
        preferred_repository_id:
          type: string
          format: uuid
          nullable: true
        license:
          type: string
    PatchedFundingAgency:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        abbreviation:
          type: string
          maxLength: 64
        url:
          type: string
          format: uri
          maxLength: 500
        openalex_id:
          type: string
          maxLength: 64
        created_at:
          type: string
          format: date-time
          readOnly: true
    PatchedGeoBoundCountrySet:
      type: object
      description: 'Versioned country-code preset used by project geobound policies

        (DSS-650). A shared global reference table: readable by any

        authenticated user (so they can pick a set) but mutated only by system

        admins (see GeoBoundCountrySet*View). ``kind`` is auto-derived as a

        ChoiceField from the model choices, so an invalid kind 400s.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        slug:
          type: string
          maxLength: 96
          pattern: ^[-a-zA-Z0-9_]+$
        name:
          type: string
          maxLength: 255
        description:
          type: string
        country_codes:
          type: array
          items:
            type: string
        kind:
          $ref: '#/components/schemas/GeoBoundCountrySetKindEnum'
        source_name:
          type: string
          maxLength: 255
        source_url:
          type: string
          format: uri
          maxLength: 200
        source_version:
          type: string
          maxLength: 128
        is_system:
          type: boolean
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
    PatchedGrantWrite:
      type: object
      description: 'User-editable subset.


        Ingest-pipeline-owned fields (raw_data, extracted_at, provenance,

        version_rev, is_latest, is_new, search_vector, funded_outputs_count)

        are NOT user-editable — they belong to the ingest layer.'
      properties:
        project:
          type: string
          format: uuid
          nullable: true
        funding_agency:
          type: string
          format: uuid
          nullable: true
        grant_id:
          type: string
          maxLength: 255
        registry_source:
          type: string
          maxLength: 64
        title:
          type: string
          maxLength: 1024
        abstract:
          type: string
          description: Short structured summary, registry-supplied (e.g. NIH abstract).
        description:
          type: string
          description: Long-form public health relevance / lay description.
        funding_amount:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          nullable: true
        currency:
          type: string
          maxLength: 16
        direct_cost_amt:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          nullable: true
        indirect_cost_amt:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          nullable: true
        award_amount:
          type: string
          format: decimal
          pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
          nullable: true
        funding_mechanism:
          type: string
          maxLength: 255
        award_type:
          type: string
          maxLength: 255
        activity_code:
          type: string
          maxLength: 64
        start_date:
          type: string
          format: date
          nullable: true
        end_date:
          type: string
          format: date
          nullable: true
        fiscal_year:
          type: integer
          maximum: 9223372036854775807
          minimum: -9223372036854775808
          format: int64
          nullable: true
        url:
          type: string
          format: uri
          maxLength: 200
        project_detail_url:
          type: string
          format: uri
          maxLength: 200
        appl_id:
          type: integer
          maximum: 9223372036854775807
          minimum: -9223372036854775808
          format: int64
          nullable: true
        subproject_id:
          type: string
          maxLength: 255
        project_num:
          type: string
          maxLength: 255
        project_serial_num:
          type: string
          maxLength: 255
        core_project_num:
          type: string
          maxLength: 255
        project_activity_code:
          type: string
          maxLength: 64
        project_suffix_code:
          type: string
          maxLength: 64
        mechanism_code_dc:
          type: string
          maxLength: 64
        is_active:
          type: boolean
        contact_pi_name:
          type: string
          maxLength: 255
        agency_ic_admin_code:
          type: string
          maxLength: 64
        agency_ic_admin_name:
          type: string
          maxLength: 255
        agency_ic_admin_abbrev:
          type: string
          maxLength: 64
        cong_dist:
          type: string
          maxLength: 64
        geo_lat:
          type: number
          format: double
          nullable: true
        geo_lon:
          type: number
          format: double
          nullable: true
        spending_category:
          type: string
          maxLength: 255
        spending_subcategory:
          type: string
          maxLength: 255
        spending_categories_desc:
          type: string
        terms:
          type: string
        pref_terms:
          type: string
        phr_text:
          type: string
        covid_response:
          type: string
          maxLength: 255
        arra_funded:
          type: string
          maxLength: 255
        cfda_code:
          type: string
          maxLength: 128
        openalex_id:
          type: string
          maxLength: 64
        custom_fields: {}
    PatchedGroupPatch:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
    PatchedMeUpdate:
      type: object
      description: 'Updatable non-email profile fields. Email changes are handled

        through a separate flow and are not accepted here.'
      properties:
        name:
          type: string
          maxLength: 255
        visible_outside_org:
          type: boolean
        custom_ollama_url:
          type: string
          maxLength: 255
        custom_ollama_model:
          type: string
          maxLength: 128
        custom_clip_service_url:
          type: string
          maxLength: 255
        custom_clip_service_token:
          type: string
          writeOnly: true
          maxLength: 4096
        ai_search_enabled:
          type: boolean
        embeddings_enabled:
          type: boolean
        default_project_geobound_enabled:
          type: boolean
        default_project_geobound_basis:
          $ref: '#/components/schemas/GeoboundBasisEnum'
        default_project_geobound_allowed_countries:
          type: array
          items:
            type: string
        default_project_geobound_allowed_country_set:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_denied_country_set:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_block_vpn:
          type: boolean
        default_project_geobound_fail_closed:
          type: boolean
        avatar_variant:
          oneOf:
          - $ref: '#/components/schemas/AvatarVariantEnum'
          - $ref: '#/components/schemas/BlankEnum'
        avatar_color:
          type: string
          maxLength: 7
        default_bibliometric_format:
          $ref: '#/components/schemas/BibliometricFormatEnum'
    PatchedOrganizationMemberWrite:
      type: object
      description: Used for POST (add member) and PATCH (change role).
      properties:
        user_id:
          type: string
          format: uuid
        role:
          $ref: '#/components/schemas/OrgMemberRoleEnum'
    PatchedOrganizationWrite:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
        description:
          type: string
        whitelisted_email_domains:
          type: array
          items:
            type: string
            maxLength: 255
        globus_identity_provider_id:
          type: string
          format: uuid
          nullable: true
          description: Globus institutional IdP UUID for auto-join on SSO signup.
        allow_external_ai:
          type: boolean
        allow_user_agent_config:
          type: boolean
        llm_provider_tier_preference:
          $ref: '#/components/schemas/LlmProviderTierPreferenceEnum'
        custom_ollama_url:
          type: string
          maxLength: 255
        custom_ollama_model:
          type: string
          maxLength: 128
        custom_clip_service_url:
          type: string
          maxLength: 255
        custom_clip_service_token:
          type: string
          writeOnly: true
          maxLength: 4096
        default_repository_id:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_configured:
          type: boolean
        default_project_geobound_enabled:
          type: boolean
        default_project_geobound_basis:
          $ref: '#/components/schemas/GeoboundBasisEnum'
        default_project_geobound_allowed_countries:
          type: array
          items:
            type: string
        default_project_geobound_allowed_country_set:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_denied_country_set:
          type: string
          format: uuid
          nullable: true
        default_project_geobound_block_vpn:
          type: boolean
        default_project_geobound_fail_closed:
          type: boolean
    PatchedProjectRole:
      type: object
      properties:
        role:
          $ref: '#/components/schemas/ProjectMemberRoleEnum'
    PatchedProjectWrite:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
        description:
          type: string
        geobound_enabled:
          type: boolean
        geobound_basis:
          $ref: '#/components/schemas/GeoboundBasisEnum'
        geobound_allowed_countries:
          type: array
          items:
            type: string
        geobound_allowed_country_set:
          type: string
          format: uuid
          nullable: true
        geobound_denied_country_set:
          type: string
          format: uuid
          nullable: true
        geobound_block_vpn:
          type: boolean
        geobound_fail_closed:
          type: boolean
    PatchedRepositoryWrite:
      type: object
      description: "Write-side fields for Repository create + partial update.\n\nTwo callable paths depending on SPAWNER_BACKEND:\n\n- Legacy (SPAWNER_BACKEND=none): admin supplies ``address`` pointing\n  at an already-running repo-agent. ``bucket`` / ``region`` /\n  ``endpoint`` / keys are ignored.\n- Console-managed (SPAWNER_BACKEND=docker or kubernetes): admin\n  supplies ``bucket`` / ``region`` / ``endpoint`` / ``access_key_id``\n  / ``secret_access_key``. ``address`` is read-only — the Console\n  computes it once the spawn succeeds.\n\nThe view picks the path."
      properties:
        name:
          type: string
          maxLength: 255
        type:
          $ref: '#/components/schemas/RepositoryTypeEnum'
        address:
          type: string
          maxLength: 1024
        capacity:
          type: integer
          minimum: 0
        bucket:
          type: string
          maxLength: 255
        region:
          type: string
          maxLength: 64
        endpoint:
          type: string
          maxLength: 1024
        access_key_id:
          type: string
          writeOnly: true
          maxLength: 255
        secret_access_key:
          type: string
          writeOnly: true
          maxLength: 1024
        access_grant:
          type: string
          writeOnly: true
        irsa_role_arn:
          type: string
          maxLength: 2048
    PatchedTransferProgress:
      type: object
      properties:
        bytes_transferred:
          type: integer
          minimum: 0
        completed_files:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: 'Upload only: [{filename, size, checksum}].'
    PathSegment:
      type: object
      properties:
        name:
          type: string
        type:
          $ref: '#/components/schemas/PathSegmentTypeEnum'
      required:
      - name
      - type
    PathSegmentTypeEnum:
      enum:
      - collection
      - asset
      type: string
      description: '* `collection` - collection

        * `asset` - asset'
    PermissionAssignmentWrite:
      type: object
      properties:
        subject_type:
          allOf:
          - $ref: '#/components/schemas/SubjectTypeEnum'
          default: user
        subject_id:
          type: string
          format: uuid
          nullable: true
        flags:
          type: integer
          minimum: 1
      required:
      - flags
    PermissionEntry:
      type: object
      properties:
        subject:
          allOf:
          - $ref: '#/components/schemas/PermissionSubject'
          readOnly: true
        flags:
          type: integer
          readOnly: true
      required:
      - flags
      - subject
    PermissionObjectTypeEnum:
      enum:
      - project
      - collection
      - asset
      - dataset
      type: string
      description: '* `project` - Project

        * `collection` - Collection

        * `asset` - Asset

        * `dataset` - Dataset'
    PermissionReplace:
      type: object
      properties:
        permissions:
          type: array
          items:
            $ref: '#/components/schemas/PermissionAssignmentWrite'
    PermissionSubject:
      type: object
      description: 'Resolve ``user.person`` once per serialization pass.


        ``user.person`` memoizes per instance, but distinct users in a list are

        distinct instances — so a list serializer would still issue one

        ``Person`` query per row. When used ``many=True`` this mixin routes

        through :class:`_PersonReadThroughListSerializer`, which calls

        ``User.attach_persons`` to batch the whole page into a single query;

        the per-render ``context`` cache below then dedups the name+email

        double-read for each user.


        The context cache lives only for the lifetime of the serializer tree,

        so one ``.data`` render resolves each distinct user''s ``Person`` at

        most once and re-batches fresh on the next render.'
      properties:
        id:
          type: string
          format: uuid
          nullable: true
        subject_type:
          type: string
        name:
          type: string
          readOnly: true
        email:
          type: string
          readOnly: true
      required:
      - email
      - id
      - name
      - subject_type
    PreprocessRequest:
      type: object
      description: "POST /datasets/.../preprocess — open-shape preprocessing parameters.\n\nThe schema of ``parameters`` is open-shape JSON: each preprocessing\nmodule owns and validates the shape of its own parameters.\n\nTwo layered size caps apply; requests exceeding either cap are\nrejected with 400:\n\n- ``PARAMETERS_MAX_BYTES`` caps the encoded JSON of ``parameters``\n  as a whole — a guard against runaway payloads.\n- ``MAX_RAW_TEXT_BYTES`` caps the ``raw_text`` carrier\n  specifically. The tabular module reads file contents from\n  ``parameters['raw_text']``, so this cap applies at much larger\n  sizes than the general parameters cap. Tunable via the\n  ``DATAERAI_MAX_RAW_TEXT_BYTES`` env var for self-hosted\n  deployments (e.g. to let dev fixtures override the default)."
      properties:
        parameters: {}
    PreprocessingJob:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        status:
          allOf:
          - $ref: '#/components/schemas/PreprocessingJobStatusEnum'
          readOnly: true
        job_runner_id:
          type: string
          readOnly: true
        queued_at:
          type: string
          format: date-time
          readOnly: true
        started_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        completed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        parameters:
          readOnly: true
      required:
      - completed_at
      - id
      - job_runner_id
      - parameters
      - queued_at
      - started_at
      - status
    PreprocessingJobStatusEnum:
      enum:
      - QUEUED
      - RUNNING
      - SUCCEEDED
      - FAILED
      - CANCELLED
      type: string
      description: '* `QUEUED` - Queued

        * `RUNNING` - Running

        * `SUCCEEDED` - Succeeded

        * `FAILED` - Failed

        * `CANCELLED` - Cancelled'
    PreviewMetadataMultipartRequest:
      type: object
      properties:
        file:
          type: string
          format: uri
      required:
      - file
    PreviewMetadataMultipartResponse:
      type: object
      properties:
        status:
          $ref: '#/components/schemas/MetadataPreviewStatusEnum'
        metadata:
          nullable: true
        data_type:
          type: string
          nullable: true
        data_type_confidence:
          type: number
          format: double
          nullable: true
        error:
          type: string
          nullable: true
      required:
      - data_type
      - data_type_confidence
      - error
      - metadata
      - status
    Project:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        description:
          type: string
        organization_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        owner_id:
          type: string
          format: uuid
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        member_count:
          type: integer
          readOnly: true
        root_collection_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        effective_flags:
          type: integer
          readOnly: true
        is_starred:
          type: boolean
          readOnly: true
        access_scope:
          type: string
          readOnly: true
        geobound_enabled:
          type: boolean
        geobound_basis:
          $ref: '#/components/schemas/GeoboundBasisEnum'
        geobound_allowed_countries:
          type: array
          items:
            type: string
            pattern: ^[A-Z]{2}$
            maxLength: 2
        geobound_allowed_country_set:
          type: string
          format: uuid
          nullable: true
        geobound_denied_country_set:
          type: string
          format: uuid
          nullable: true
        geobound_block_vpn:
          type: boolean
        geobound_fail_closed:
          type: boolean
      required:
      - access_scope
      - created_at
      - effective_flags
      - id
      - is_starred
      - member_count
      - name
      - organization_id
      - owner_id
      - root_collection_id
      - updated_at
    ProjectDetail:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        description:
          type: string
        organization_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        owner_id:
          type: string
          format: uuid
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        member_count:
          type: integer
          readOnly: true
        root_collection_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        effective_flags:
          type: integer
          readOnly: true
        is_starred:
          type: boolean
          readOnly: true
        access_scope:
          type: string
          readOnly: true
        geobound_enabled:
          type: boolean
        geobound_basis:
          $ref: '#/components/schemas/GeoboundBasisEnum'
        geobound_allowed_countries:
          type: array
          items:
            type: string
            pattern: ^[A-Z]{2}$
            maxLength: 2
        geobound_allowed_country_set:
          type: string
          format: uuid
          nullable: true
        geobound_denied_country_set:
          type: string
          format: uuid
          nullable: true
        geobound_block_vpn:
          type: boolean
        geobound_fail_closed:
          type: boolean
        current_user_role:
          type: string
          readOnly: true
      required:
      - access_scope
      - created_at
      - current_user_role
      - effective_flags
      - id
      - is_starred
      - member_count
      - name
      - organization_id
      - owner_id
      - root_collection_id
      - updated_at
    ProjectMember:
      type: object
      properties:
        user:
          allOf:
          - $ref: '#/components/schemas/ProjectMemberUser'
          readOnly: true
        role:
          allOf:
          - $ref: '#/components/schemas/ProjectMemberRoleEnum'
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - role
      - user
    ProjectMemberRoleEnum:
      enum:
      - member
      - manager
      - admin
      type: string
      description: '* `member` - Member

        * `manager` - Manager

        * `admin` - Admin'
    ProjectMemberUser:
      type: object
      description: 'Resolve ``user.person`` once per serialization pass.


        ``user.person`` memoizes per instance, but distinct users in a list are

        distinct instances — so a list serializer would still issue one

        ``Person`` query per row. When used ``many=True`` this mixin routes

        through :class:`_PersonReadThroughListSerializer`, which calls

        ``User.attach_persons`` to batch the whole page into a single query;

        the per-render ``context`` cache below then dedups the name+email

        double-read for each user.


        The context cache lives only for the lifetime of the serializer tree,

        so one ``.data`` render resolves each distinct user''s ``Person`` at

        most once and re-batches fresh on the next render.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        email:
          type: string
          readOnly: true
        name:
          type: string
          readOnly: true
      required:
      - email
      - id
      - name
    ProjectMemberWrite:
      type: object
      properties:
        user_id:
          type: string
          format: uuid
        role:
          $ref: '#/components/schemas/ProjectMemberRoleEnum'
      required:
      - user_id
    ProjectWrite:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
        description:
          type: string
        geobound_enabled:
          type: boolean
        geobound_basis:
          $ref: '#/components/schemas/GeoboundBasisEnum'
        geobound_allowed_countries:
          type: array
          items:
            type: string
        geobound_allowed_country_set:
          type: string
          format: uuid
          nullable: true
        geobound_denied_country_set:
          type: string
          format: uuid
          nullable: true
        geobound_block_vpn:
          type: boolean
        geobound_fail_closed:
          type: boolean
      required:
      - name
    ProvisioningStatusEnum:
      enum:
      - pending
      - ready
      - failed
      type: string
      description: '* `pending` - Pending

        * `ready` - Ready

        * `failed` - Failed'
    RecordTypeEnum:
      enum:
      - dataset
      - sample_specimen
      - synthesis
      - fabrication
      - processing
      - assembly
      - measurement
      - imaging
      - spectroscopy
      - diffraction_scattering
      - mechanical_testing
      - thermal_analysis
      - electrical_testing
      - chemical_assay
      - biological_assay
      - environmental_observation
      - calibration
      - quality_control
      - simulation
      - analysis
      - protocol_workflow
      - software_code
      type: string
      description: '* `dataset` - Dataset

        * `sample_specimen` - Sample / Specimen

        * `synthesis` - Synthesis

        * `fabrication` - Fabrication

        * `processing` - Processing

        * `assembly` - Assembly

        * `measurement` - Measurement

        * `imaging` - Imaging

        * `spectroscopy` - Spectroscopy

        * `diffraction_scattering` - Diffraction / Scattering

        * `mechanical_testing` - Mechanical Testing

        * `thermal_analysis` - Thermal Analysis

        * `electrical_testing` - Electrical Testing

        * `chemical_assay` - Chemical Assay

        * `biological_assay` - Biological Assay

        * `environmental_observation` - Environmental Observation

        * `calibration` - Calibration

        * `quality_control` - Quality Control

        * `simulation` - Simulation

        * `analysis` - Analysis

        * `protocol_workflow` - Protocol / Workflow

        * `software_code` - Software / Code'
    RelatedAssetSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          readOnly: true
        alias:
          type: string
          readOnly: true
          nullable: true
      required:
      - alias
      - id
      - title
    RemoveSubject:
      type: object
      properties:
        subject_type:
          allOf:
          - $ref: '#/components/schemas/SubjectTypeEnum'
          default: user
        subject_id:
          type: string
          format: uuid
          nullable: true
    Reply:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        author:
          allOf:
          - $ref: '#/components/schemas/NoteAuthor'
          readOnly: true
        content:
          type: string
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - author
      - content
      - created_at
      - id
    Repository:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        type:
          $ref: '#/components/schemas/RepositoryTypeEnum'
        address:
          type: string
          maxLength: 1024
        capacity:
          type: integer
          maximum: 9223372036854775807
          minimum: -9223372036854775808
          format: int64
        is_active:
          type: boolean
        usage_bytes:
          type: integer
          format: int64
          readOnly: true
        asset_content_count:
          type: integer
          format: int64
          readOnly: true
        bucket:
          type: string
          maxLength: 255
        region:
          type: string
          maxLength: 64
        endpoint:
          type: string
          maxLength: 1024
        access_key_id_masked:
          type: string
          nullable: true
          readOnly: true
        irsa_role_arn:
          type: string
          maxLength: 2048
        provider:
          type: string
          readOnly: true
        provisioning_status:
          allOf:
          - $ref: '#/components/schemas/ProvisioningStatusEnum'
          readOnly: true
        provisioning_error:
          type: string
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - access_key_id_masked
      - address
      - asset_content_count
      - capacity
      - created_at
      - id
      - name
      - provider
      - provisioning_error
      - provisioning_status
      - type
      - updated_at
      - usage_bytes
    RepositoryTypeEnum:
      enum:
      - s3
      - storj
      - posix
      type: string
      description: '* `s3` - S3

        * `storj` - Storj

        * `posix` - POSIX'
    RepositoryWrite:
      type: object
      description: "Write-side fields for Repository create + partial update.\n\nTwo callable paths depending on SPAWNER_BACKEND:\n\n- Legacy (SPAWNER_BACKEND=none): admin supplies ``address`` pointing\n  at an already-running repo-agent. ``bucket`` / ``region`` /\n  ``endpoint`` / keys are ignored.\n- Console-managed (SPAWNER_BACKEND=docker or kubernetes): admin\n  supplies ``bucket`` / ``region`` / ``endpoint`` / ``access_key_id``\n  / ``secret_access_key``. ``address`` is read-only — the Console\n  computes it once the spawn succeeds.\n\nThe view picks the path."
      properties:
        name:
          type: string
          maxLength: 255
        type:
          $ref: '#/components/schemas/RepositoryTypeEnum'
        address:
          type: string
          maxLength: 1024
        capacity:
          type: integer
          minimum: 0
        bucket:
          type: string
          maxLength: 255
        region:
          type: string
          maxLength: 64
        endpoint:
          type: string
          maxLength: 1024
        access_key_id:
          type: string
          writeOnly: true
          maxLength: 255
        secret_access_key:
          type: string
          writeOnly: true
          maxLength: 1024
        access_grant:
          type: string
          writeOnly: true
        irsa_role_arn:
          type: string
          maxLength: 2048
      required:
      - capacity
      - name
      - type
    SourceEnum:
      enum:
      - native
      - zenodo
      - databank
      - figshare
      - mdf
      - dryad
      - osf
      - mendeley
      - dataverse
      - huggingface
      - fourtu
      - cern
      - sciencebase
      - gbif
      - biostudies
      - pdb
      - pride
      - nomad
      - pangaea
      - cmr
      - pubchem
      - uniprot
      - ncbigeo
      - chembl
      - openml
      - datacite
      - dataone
      - noaa
      - cod
      - clinicaltrials
      - worldbank
      - ena
      - openneuro
      - empiar
      - mast
      - tcia
      - internetarchive
      - fooddata
      - nga
      type: string
      description: '* `native` - Native

        * `zenodo` - Zenodo

        * `databank` - Illinois Data Bank

        * `figshare` - Figshare

        * `mdf` - Materials Data Facility

        * `dryad` - Dryad

        * `osf` - OSF

        * `mendeley` - Mendeley

        * `dataverse` - Dataverse

        * `huggingface` - Hugging Face

        * `fourtu` - 4TU.ResearchData

        * `cern` - CERN Open Data

        * `sciencebase` - USGS ScienceBase

        * `gbif` - GBIF

        * `biostudies` - EMBL-EBI BioStudies

        * `pdb` - RCSB Protein Data Bank

        * `pride` - EMBL-EBI PRIDE

        * `nomad` - NOMAD

        * `pangaea` - PANGAEA

        * `cmr` - NASA Earthdata (CMR)

        * `pubchem` - PubChem

        * `uniprot` - UniProt

        * `ncbigeo` - NCBI GEO

        * `chembl` - ChEMBL

        * `openml` - OpenML

        * `datacite` - DataCite

        * `dataone` - DataONE

        * `noaa` - NOAA NCEI

        * `cod` - Crystallography Open Database

        * `clinicaltrials` - ClinicalTrials.gov

        * `worldbank` - World Bank

        * `ena` - ENA

        * `openneuro` - OpenNeuro

        * `empiar` - EMPIAR

        * `mast` - MAST

        * `tcia` - TCIA

        * `internetarchive` - Internet Archive

        * `fooddata` - FoodData Central

        * `nga` - National Gallery of Art'
    SubjectTypeEnum:
      enum:
      - user
      - group
      - public
      type: string
      description: '* `user` - User

        * `group` - Group

        * `public` - Public'
    Transfer:
      type: object
      description: 'Read-only representation of a transfer.


        Includes denormalized labels (``project_name``, ``repository_name``,

        ``asset_content_title``) so the client can render one row per

        transfer without extra round-trips. Transfers are visible only to

        the user who initiated them (GET /transfers/ lists the caller''s own

        transfers), and the labels reflect what the initiator could see at

        initiation time — they remain readable even if the underlying

        access grant is later revoked. ``project_*`` and ``repository_*``

        fields are nullable — an asset may have no owning project, and its

        storage allocation may have been detached — clients MUST handle

        null.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        asset_content_id:
          type: string
          format: uuid
          readOnly: true
        type:
          allOf:
          - $ref: '#/components/schemas/TransferTypeEnum'
          readOnly: true
        status:
          allOf:
          - $ref: '#/components/schemas/TransferStatusEnum'
          readOnly: true
        origin:
          allOf:
          - $ref: '#/components/schemas/TransferOriginEnum'
          readOnly: true
        bytes_transferred:
          type: integer
          readOnly: true
        expires_at:
          type: string
          format: date-time
          readOnly: true
        initiated_by_id:
          type: string
          format: uuid
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        asset_content_title:
          type: string
          readOnly: true
        project_id:
          type: string
          format: uuid
          readOnly: true
        project_name:
          type: string
          readOnly: true
        repository_id:
          type: string
          format: uuid
          readOnly: true
        repository_name:
          type: string
          readOnly: true
        total_bytes:
          type: integer
          readOnly: true
          default: 0
        direction_supports_progress:
          type: boolean
          readOnly: true
        executor:
          allOf:
          - $ref: '#/components/schemas/ExecutorEnum'
          readOnly: true
        delivery_target:
          readOnly: true
        claimed_by_endpoint_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        claimed_endpoint_name:
          type: string
          readOnly: true
        lease_expires_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
      required:
      - asset_content_id
      - asset_content_title
      - bytes_transferred
      - claimed_by_endpoint_id
      - claimed_endpoint_name
      - created_at
      - delivery_target
      - direction_supports_progress
      - executor
      - expires_at
      - id
      - initiated_by_id
      - lease_expires_at
      - origin
      - project_id
      - project_name
      - repository_id
      - repository_name
      - status
      - total_bytes
      - type
      - updated_at
    TransferCompleteRequest:
      type: object
      properties:
        extracted_metadata:
          nullable: true
        skip_extraction:
          type: boolean
          default: false
    TransferCredentialsResponse:
      type: object
      properties:
        credentials:
          type: object
          additionalProperties: {}
        endpoint:
          type: string
        prefix:
          type: string
        expires_at:
          type: string
          format: date-time
      required:
      - credentials
      - endpoint
      - expires_at
      - prefix
    TransferFilterProject:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
      required:
      - id
      - name
    TransferFilterRepository:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
      required:
      - id
      - name
    TransferFiltersResponse:
      type: object
      properties:
        projects:
          type: array
          items:
            $ref: '#/components/schemas/TransferFilterProject'
        repositories:
          type: array
          items:
            $ref: '#/components/schemas/TransferFilterRepository'
      required:
      - projects
      - repositories
    TransferInitiate:
      type: object
      properties:
        content_id:
          type: string
          format: uuid
        type:
          $ref: '#/components/schemas/TransferInitiateTypeEnum'
        files:
          type: array
          items:
            type: string
          description: 'Upload only: list of filenames to transfer.'
        expires_in:
          type: integer
          maximum: 604800
          minimum: 60
          default: 86400
          description: TTL in seconds (default 86400 = 1 day).
        supported_protocols:
          type: array
          items:
            type: string
          description: Preferred transfer protocols, e.g. ['s3']. Accepted but not yet used in credential selection.
        origin:
          allOf:
          - $ref: '#/components/schemas/TransferInitiateOriginEnum'
          default: user
          description: 'Transfer source. ''system'' is used for internal fetches (e.g. README auto-load) and is filtered out of the tracker list by default.


            * `user` - user

            * `system` - system'
      required:
      - content_id
      - type
    TransferInitiateOriginEnum:
      enum:
      - user
      - system
      type: string
      description: '* `user` - user

        * `system` - system'
    TransferInitiateResponse:
      type: object
      properties:
        transfer_id:
          type: string
          format: uuid
        credentials:
          type: object
          additionalProperties: {}
        endpoint:
          type: string
        prefix:
          type: string
        files:
          type: array
          items:
            type: object
            additionalProperties: {}
        expires_at:
          type: string
          format: date-time
      required:
      - credentials
      - endpoint
      - expires_at
      - files
      - prefix
      - transfer_id
    TransferInitiateTypeEnum:
      enum:
      - upload
      - download
      type: string
      description: '* `upload` - upload

        * `download` - download'
    TransferMetadataPreviewResponse:
      type: object
      properties:
        status:
          $ref: '#/components/schemas/MetadataPreviewStatusEnum'
        metadata:
          nullable: true
        data_type:
          type: string
          nullable: true
        data_type_confidence:
          type: number
          format: double
          nullable: true
        error:
          type: string
          nullable: true
      required:
      - data_type
      - data_type_confidence
      - error
      - metadata
      - status
    TransferOriginEnum:
      enum:
      - user
      - system
      type: string
      description: '* `user` - User

        * `system` - System'
    TransferStatusEnum:
      enum:
      - pending
      - claimed
      - in_progress
      - completed
      - failed
      - expired
      type: string
      description: '* `pending` - Pending

        * `claimed` - Claimed

        * `in_progress` - In Progress

        * `completed` - Completed

        * `failed` - Failed

        * `expired` - Expired'
    TransferTypeEnum:
      enum:
      - upload
      - download
      type: string
      description: '* `upload` - Upload

        * `download` - Download'
    User:
      type: object
      description: 'Resolve ``user.person`` once per serialization pass.


        ``user.person`` memoizes per instance, but distinct users in a list are

        distinct instances — so a list serializer would still issue one

        ``Person`` query per row. When used ``many=True`` this mixin routes

        through :class:`_PersonReadThroughListSerializer`, which calls

        ``User.attach_persons`` to batch the whole page into a single query;

        the per-render ``context`` cache below then dedups the name+email

        double-read for each user.


        The context cache lives only for the lifetime of the serializer tree,

        so one ``.data`` render resolves each distinct user''s ``Person`` at

        most once and re-batches fresh on the next render.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        email:
          type: string
          readOnly: true
        name:
          type: string
          readOnly: true
        is_system_admin:
          type: boolean
          readOnly: true
        is_repository_admin:
          type: boolean
          readOnly: true
        date_joined:
          type: string
          format: date-time
          readOnly: true
      required:
      - date_joined
      - email
      - id
      - is_repository_admin
      - is_system_admin
      - name
    UserSearch:
      type: object
      description: 'Resolve ``user.person`` once per serialization pass.


        ``user.person`` memoizes per instance, but distinct users in a list are

        distinct instances — so a list serializer would still issue one

        ``Person`` query per row. When used ``many=True`` this mixin routes

        through :class:`_PersonReadThroughListSerializer`, which calls

        ``User.attach_persons`` to batch the whole page into a single query;

        the per-render ``context`` cache below then dedups the name+email

        double-read for each user.


        The context cache lives only for the lifetime of the serializer tree,

        so one ``.data`` render resolves each distinct user''s ``Person`` at

        most once and re-batches fresh on the next render.'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        email:
          type: string
          readOnly: true
      required:
      - email
      - id
      - name
    WorkCitation:
      type: object
      description: 'An OpenAlex Work shaped for the sidebar citation exporter.


        ``authors`` / ``venue`` / ``biblio`` are read off the stored OpenAlex

        ``metadata`` payload — the same extraction beta''s unified works search uses

        for its result rows (``works_search_views._authors_from_work_dict`` /

        ``_venue_from_work_dict``) — so rendering one linked work needs NO

        WorkAuthor / Person / Source joins. Read-only; Works are ingested data.


        Defined above ``AssetSerializer`` so its ``cited_work`` field can reference

        this class in ``@extend_schema_field`` (which also registers the component).'
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        openalex_id:
          type: string
          readOnly: true
        doi:
          type: string
          readOnly: true
        title:
          type: string
          readOnly: true
        display_name:
          type: string
          readOnly: true
        publication_year:
          type: integer
          readOnly: true
          nullable: true
        publication_date:
          type: string
          format: date
          readOnly: true
          nullable: true
        authors:
          type: array
          items:
            type: object
            properties:
              full_name:
                type: string
          readOnly: true
        venue:
          type: string
          nullable: true
          readOnly: true
        biblio:
          type: object
          properties:
            volume:
              type: string
              nullable: true
            issue:
              type: string
              nullable: true
            first_page:
              type: string
              nullable: true
            last_page:
              type: string
              nullable: true
          readOnly: true
      required:
      - authors
      - biblio
      - display_name
      - doi
      - id
      - openalex_id
      - publication_date
      - publication_year
      - title
      - venue
    _SlimOrg:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
      required:
      - id
      - name
