> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gumnut.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Update metadata on multiple assets

> Updates metadata on multiple assets in one transactional call. Each item carries the target asset id and the per-asset change — different fields can be changed on different assets in the same request. Atomic: any per-item validation failure or unknown / cross-user id rejects the whole batch and writes nothing.

Up to 100 items per request; over-cap requests return 422. For a single-asset edit, prefer `update_asset` — semantically identical but slightly more concise at the call site.



## OpenAPI

````yaml https://api.gumnut.ai/openapi.json post /api/assets/bulk-update
openapi: 3.1.0
info:
  title: Gumnut API
  description: API for using Gumnut to manage photos and videos
  version: 0.1.0
servers: []
security: []
paths:
  /api/assets/bulk-update:
    post:
      tags:
        - assets
      summary: Update metadata on multiple assets
      description: >-
        Updates metadata on multiple assets in one transactional call. Each item
        carries the target asset id and the per-asset change — different fields
        can be changed on different assets in the same request. Atomic: any
        per-item validation failure or unknown / cross-user id rejects the whole
        batch and writes nothing.


        Up to 100 items per request; over-cap requests return 422. For a
        single-asset edit, prefer `update_asset` — semantically identical but
        slightly more concise at the call site.
      operationId: bulk_update_assets
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkUpdateAssetsRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkUpdateAssetsResponse'
        '404':
          description: Not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    BulkUpdateAssetsRequest:
      properties:
        updates:
          items:
            $ref: '#/components/schemas/BulkUpdateAssetItem'
          type: array
          maxItems: 100
          minItems: 1
          title: Updates
          description: >-
            List of per-asset updates. Each item carries the target asset id and
            the change to apply to it; different fields can be changed on
            different assets in the same request. Up to 100 items per request.
      type: object
      required:
        - updates
      title: BulkUpdateAssetsRequest
      description: Bulk-update request body — heterogeneous per-asset changes in one call.
    BulkUpdateAssetsResponse:
      properties: {}
      type: object
      title: BulkUpdateAssetsResponse
      description: |-
        Acknowledgment body for ``POST /api/assets/bulk-update``.

        Empty by design; exists so MCP tools generated from this endpoint have a
        real ``outputSchema``. Distinct from ``DeletionResponse`` because that
        name is purpose-scoped to destructive operations — reusing it on a
        non-destructive endpoint would misname the wire shape in OpenAPI and
        generated SDKs.
      x-stainless-empty-object: true
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    BulkUpdateAssetItem:
      properties:
        id:
          type: string
          title: Id
          description: >-
            Asset ID (with the `asset_` prefix) to apply this change to. Obtain
            from `list_assets`, `search_assets`, or `list_album_assets`.
        change:
          $ref: '#/components/schemas/UpdateAssetRequest'
          description: >-
            The change to apply to this asset. Same shape as the body of the
            single-asset `update_asset` endpoint — same fields, same validation,
            same null-clears-the-override semantics.
      type: object
      required:
        - id
        - change
      title: BulkUpdateAssetItem
      description: |-
        One item in a bulk-update request.

        Names the target asset and carries the per-asset change to apply. The
        ``change`` object is exactly the body shape that the single-asset
        ``PATCH /api/assets/{asset_id}`` endpoint accepts; the wrapper exists so
        operation-level metadata (``id``, future ``if_match`` / idempotency-key
        fields) stays in a namespace disjoint from the entity-field changes.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    UpdateAssetRequest:
      properties:
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: >-
            User-set description for the asset. Pass ``null`` to remove a
            previously-set value (the response then falls back to the
            description embedded in the file, if any). Omit to leave unchanged.
            Distinct from the AI-generated `description` field on the response —
            this writes to `metadata.description`.
        latitude:
          anyOf:
            - type: number
            - type: 'null'
          title: Latitude
          description: >-
            GPS latitude in decimal degrees, ``[-90, 90]``. Must be set together
            with ``longitude``. Pass ``null`` (along with ``longitude=null``) to
            remove a previously-set value; omit to leave unchanged.
        longitude:
          anyOf:
            - type: number
            - type: 'null'
          title: Longitude
          description: >-
            GPS longitude in decimal degrees, ``[-180, 180]``. Must be set
            together with ``latitude``. Pass ``null`` (along with
            ``latitude=null``) to remove a previously-set value; omit to leave
            unchanged.
        original_datetime:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Original Datetime
          description: >-
            When the asset was originally captured. Aware values store the
            offset from ``utcoffset()`` alongside; naive values store NULL
            offset. Pass ``null`` to remove a previously-set value — the
            response then falls back to the datetime embedded in the file when
            present, otherwise to the file's upload timestamp. Omit to leave
            unchanged.
      additionalProperties: true
      type: object
      title: UpdateAssetRequest
      description: >-
        User-editable metadata for a single asset.


        Mirrors the field shape of ``UserAssetMetadataUpdate``; the service
        model

        owns cross-field validation. See
        ``photos-api/docs/references/api-design.md``

        for the router-DTO + service-model pattern.

````