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

# Bulk upsert photos

> Bulk upsert external photos into a BuildPass photo folder idempotently.

Requires `write:photos`. Bulk upserts photos into a project gallery folder. `projectId` is required and must belong to the builder.

Upload attachment bytes first with `POST /builders/{builderId}/attachments/bulk-upload`, then pass each returned `{ key, regionId, type }` as `photos[].imageAttachment`. This endpoint accepts JSON only.

Approved HTTPS `imageUrl` imports are supported only for hosts reviewed and enabled by BuildPass. If you want to import photos from your own image URL hosts, please contact BuildPass. The endpoint is idempotent by `metadata.externalSourceId`, so repeated sends skip existing photos.

When syncing the same external source again, pass the previously returned `folderId` so new photos are added to the same BuildPass folder. Omit `folderId` for a different external source, even when the folder name and date are the same.

Use `DELETE /builders/{builderId}/photo-gallery/bulk-upsert` with the same
`externalSourceId` and the currently selected `projectId` to archive photos
created for that external source and remove its now-empty persisted folder when
possible. The project identifies the caller's authorized BuildPass context;
the deletion target is resolved from the external source's persisted metadata,
which allows cleanup after the selected project changes. `folderId` remains
accepted for request compatibility but is not used as deletion authority.
For a retry after a prior copy was archived, an unclaimed folder ID may be
recreated in the authorized destination project; an ID already owned by another
project is rejected.


## OpenAPI

````yaml POST /builders/{builderId}/photo-gallery/bulk-upsert
openapi: 3.0.0
info:
  title: BuildPass API
  description: >-
    Approved integrators can connect to the BuildPass API on behalf of builders
    to build connections between a wide range of construction platforms.
  version: 1.0.0
servers:
  - url: https://api.buildpass.global
    description: Production server
security:
  - OAuth2: []
paths:
  /builders/{builderId}/photo-gallery/bulk-upsert:
    post:
      tags:
        - Photos
      summary: Bulk upsert photos
      description: Bulk upsert external photos into a BuildPass photo folder idempotently.
      parameters:
        - name: builderId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PhotoGallerySyncInput'
      responses:
        '200':
          description: Photos synced
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PhotoGallerySyncResponse'
      security:
        - OAuth2:
            - write:photos
components:
  schemas:
    PhotoGallerySyncInput:
      type: object
      required:
        - externalSourceId
        - sourceApp
        - projectId
        - folderName
        - photos
      properties:
        externalSourceId:
          type: string
          example: supasite:photo-page:page_123
        folderId:
          type: string
          description: >-
            Existing BuildPass photo folder id for this external source. Omit on
            first upsert to create a new folder.
        sourceApp:
          type: string
          example: supasite
        projectId:
          type: string
          example: proj_ckproject123456789012345678
        folderName:
          type: string
          example: Site walkthrough - 2026-06-11
        photos:
          type: array
          items:
            type: object
            required:
              - externalSourceId
              - fileName
              - contentType
              - sequenceId
            properties:
              externalSourceId:
                type: string
              imageUrl:
                type: string
                format: uri
                description: >-
                  Approved HTTPS URL import host enabled by BuildPass. Prefer
                  imageAttachment from the attachment upload endpoints.
              imageAttachment:
                $ref: '#/components/schemas/AttachmentUploadReference'
              fileName:
                type: string
              contentType:
                type: string
              sequenceId:
                type: number
              width:
                type: number
              height:
                type: number
              capturedAt:
                type: string
                format: date-time
    PhotoGallerySyncResponse:
      type: object
      properties:
        folderId:
          type: string
        createdAttachmentIds:
          type: array
          items:
            type: string
        skippedExternalSourceIds:
          type: array
          items:
            type: string
        failedPhotos:
          type: array
          items:
            type: object
        status:
          type: string
          enum:
            - synced
            - partial
    AttachmentUploadReference:
      type: object
      required:
        - key
        - type
      properties:
        key:
          type: string
          example: external-uploads/ckbuilder123456789012345678/photo.jpg
        regionId:
          type: string
          nullable: true
          example: au1
        type:
          type: string
          enum:
            - attachment
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://api.buildpass.global/oauth/token
          scopes:
            read:subcontractors: Read subcontractors
            write:subcontractors: Write subcontractors
            read:prequalifications: Read prequalifications
            write:prequalifications: Write prequalifications
            read:insurances: Read insurances
            write:insurances: Write insurances
            read:contacts: Read contacts
            read:swms: Read SWMS
            read:timesheets: Read timesheets
            read:inductions: Read inductions
            read:meetings: Read meetings
            write:meetings: Write meetings
            read:photos: Read photos and photo folders
            write:photos: Create, update, delete, and sync photos and photo folders

````