> ## 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.

# Sync a photo report

> Creates or updates a photo report in BuildPass, including its title, text, photos and optional project. Use this endpoint to keep reports from your application in sync with BuildPass.

Requires `write:photos`.

Send the complete report’s title, text and image blocks in `page`. Upload photos using [bulk upsert photos](/api-reference/builders/photo-gallery/bulk-upsert), then include the returned attachment IDs in the report.

Keep `sourceExternalId` the same for each report and increase `sourceRevision` when its content changes. Retry with the same revision and content; outdated or conflicting revisions return `409`.

Use `PATCH` to update an existing report and `DELETE` to archive it. Send a newer revision with `POST` to restore an archived report.


## OpenAPI

````yaml POST /builders/{builderId}/photo-reports/sync
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-reports/sync:
    post:
      tags:
        - Photos
      summary: Sync a photo report
      description: >-
        Creates or updates a photo report in BuildPass, including its title,
        text, photos and optional project. Use this endpoint to keep reports
        from your application in sync with BuildPass.
      operationId: postPhotoReport
      parameters:
        - name: builderId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PhotoReportSyncRequest'
      responses:
        '200':
          description: Snapshot committed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PhotoReportSyncResponse'
        '400':
          description: Invalid document, ID, revision or request shape
        '401':
          description: Missing or invalid token
        '403':
          description: Missing write:photos scope or builder access
        '404':
          description: Builder/project inaccessible or source report not found for archive
        '409':
          description: Revision, ownership or attachment conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PhotoReportConflict'
        '429':
          description: Rate limit exceeded
        '500':
          description: Save failed; retry identical source revision and snapshot
      security:
        - OAuth2:
            - write:photos
components:
  schemas:
    PhotoReportSyncRequest:
      type: object
      properties:
        sourceApp:
          type: string
          minLength: 1
          maxLength: 80
        sourceExternalId:
          type: string
          minLength: 1
          maxLength: 220
        sourceRevision:
          type: integer
          minimum: 1
          maximum: 2147483647
        sourceCreatedAt:
          type: string
          minLength: 1
          format: date-time
        walkthroughDate:
          type: string
          minLength: 1
          format: date-time
        sourceAuthor:
          $ref: '#/components/schemas/PhotoReportSourceAuthor'
        mappedAdminUserId:
          type: string
          minLength: 1
          pattern: ^user_[a-z][a-z0-9]+$
        sourceDeepLink:
          type: string
          minLength: 1
          maxLength: 1000
          description: HTTPS or supasite URI with no credentials, query string or fragment.
        projectId:
          type: string
          minLength: 1
          pattern: ^proj_[a-z][a-z0-9]+$
          nullable: true
        page:
          $ref: '#/components/schemas/PageDocumentV1'
      required:
        - sourceApp
        - sourceExternalId
        - sourceRevision
        - sourceCreatedAt
        - walkthroughDate
        - sourceAuthor
        - page
    PhotoReportSyncResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - synced
            - partial
        idempotent:
          type: boolean
        photoReportId:
          type: string
          minLength: 1
          pattern: ^phrep_
        pageId:
          type: string
          minLength: 1
          pattern: ^page_
        sourceRevision:
          type: integer
          minimum: 1
          maximum: 2147483647
      required:
        - status
        - idempotent
        - photoReportId
        - pageId
        - sourceRevision
    PhotoReportConflict:
      type: object
      properties:
        code:
          type: string
          enum:
            - STALE_REVISION
            - REVISION_CONFLICT
            - ATTACHMENT_CONFLICT
            - SOURCE_OWNERSHIP_REQUIRED
        message:
          type: string
      required:
        - code
        - message
    PhotoReportSourceAuthor:
      type: object
      properties:
        externalId:
          type: string
          minLength: 1
          maxLength: 220
        name:
          type: string
          minLength: 1
          maxLength: 240
        email:
          type: string
          minLength: 1
          maxLength: 320
          format: email
      required:
        - externalId
        - name
    PageDocumentV1:
      type: object
      properties:
        schemaVersion:
          type: integer
          enum:
            - 1
        title:
          type: string
          maxLength: 20000
        shortDescription:
          type: string
          nullable: true
          maxLength: 20000
        contentMetadata:
          type: object
          additionalProperties: true
        sharingMetadata:
          type: object
          additionalProperties: true
        blocks:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/PageTextBlock'
              - $ref: '#/components/schemas/PageHeadingBlock'
              - $ref: '#/components/schemas/PageBulletedListBlock'
              - $ref: '#/components/schemas/PageOrderedListBlock'
              - $ref: '#/components/schemas/PageChecklistBlock'
              - $ref: '#/components/schemas/PageImageBlock'
              - $ref: '#/components/schemas/PagePageBlock'
          maxItems: 500
      required:
        - schemaVersion
        - title
        - blocks
      description: >-
        Authoritative snapshot. Maximum 500 blocks across the whole tree and
        four Page levels including root. Source block IDs are unique among
        siblings.
    PageTextBlock:
      type: object
      properties:
        sourceBlockId:
          type: string
          minLength: 1
          maxLength: 220
        type:
          type: string
          enum:
            - TEXT
        properties:
          type: object
          additionalProperties: true
        richText:
          $ref: '#/components/schemas/PageRichText'
      required:
        - sourceBlockId
        - type
        - properties
        - richText
    PageHeadingBlock:
      type: object
      properties:
        sourceBlockId:
          type: string
          minLength: 1
          maxLength: 220
        type:
          type: string
          enum:
            - HEADING
        properties:
          type: object
          properties:
            level:
              type: integer
              minimum: 1
              maximum: 4
          required:
            - level
          additionalProperties: true
        richText:
          $ref: '#/components/schemas/PageRichText'
      required:
        - sourceBlockId
        - type
        - properties
        - richText
    PageBulletedListBlock:
      type: object
      properties:
        sourceBlockId:
          type: string
          minLength: 1
          maxLength: 220
        type:
          type: string
          enum:
            - BULLETED_LIST
        properties:
          type: object
          properties:
            items:
              type: array
              items:
                $ref: '#/components/schemas/PageListItem'
              minItems: 1
              maxItems: 100
              description: Item IDs must be unique within the list.
          required:
            - items
          additionalProperties: true
      required:
        - sourceBlockId
        - type
        - properties
    PageOrderedListBlock:
      type: object
      properties:
        sourceBlockId:
          type: string
          minLength: 1
          maxLength: 220
        type:
          type: string
          enum:
            - ORDERED_LIST
        properties:
          type: object
          properties:
            items:
              type: array
              items:
                $ref: '#/components/schemas/PageListItem'
              minItems: 1
              maxItems: 100
              description: Item IDs must be unique within the list.
          required:
            - items
          additionalProperties: true
      required:
        - sourceBlockId
        - type
        - properties
    PageChecklistBlock:
      type: object
      properties:
        sourceBlockId:
          type: string
          minLength: 1
          maxLength: 220
        type:
          type: string
          enum:
            - CHECKLIST
        properties:
          type: object
          properties:
            items:
              type: array
              items:
                $ref: '#/components/schemas/PageChecklistItem'
              minItems: 1
              maxItems: 100
              description: Item IDs must be unique within the list.
          required:
            - items
          additionalProperties: true
      required:
        - sourceBlockId
        - type
        - properties
    PageImageBlock:
      type: object
      properties:
        sourceBlockId:
          type: string
          minLength: 1
          maxLength: 220
        type:
          type: string
          enum:
            - IMAGE
        properties:
          type: object
          additionalProperties: true
        attachmentId:
          type: string
          minLength: 1
          nullable: true
          pattern: ^att_[a-z][a-z0-9]+$
        captureSequenceId:
          type: number
        imageStatus:
          type: string
          enum:
            - SYNCED
            - FAILED
        imageFailure:
          type: object
          properties:
            code:
              type: string
              minLength: 1
              maxLength: 80
            message:
              type: string
              minLength: 1
              maxLength: 500
          required:
            - code
            - message
      required:
        - sourceBlockId
        - type
        - properties
        - attachmentId
        - imageStatus
      oneOf:
        - properties:
            imageStatus:
              enum:
                - SYNCED
            attachmentId:
              type: string
              minLength: 1
              pattern: ^att_[a-z][a-z0-9]+$
        - required:
            - imageFailure
          properties:
            imageStatus:
              enum:
                - FAILED
            attachmentId:
              type: string
              nullable: true
              enum:
                - null
    PagePageBlock:
      type: object
      properties:
        sourceBlockId:
          type: string
          minLength: 1
          maxLength: 220
        type:
          type: string
          enum:
            - PAGE
        properties:
          type: object
          additionalProperties: true
        childPage:
          $ref: '#/components/schemas/PageDocumentV1'
      required:
        - sourceBlockId
        - type
        - properties
        - childPage
    PageRichText:
      type: array
      items:
        type: object
        properties:
          text:
            type: string
          marks:
            type: array
            items:
              type: string
              enum:
                - BOLD
                - ITALIC
            maxItems: 2
            default: []
        required:
          - text
      minItems: 1
      maxItems: 200
      description: At most 200 runs and 20,000 total text characters per rich-text field.
    PageListItem:
      type: object
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 220
        depth:
          type: integer
          minimum: 0
          maximum: 6
        richText:
          $ref: '#/components/schemas/PageRichText'
      required:
        - id
        - richText
      additionalProperties: false
    PageChecklistItem:
      type: object
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 220
        depth:
          type: integer
          minimum: 0
          maximum: 6
        richText:
          $ref: '#/components/schemas/PageRichText'
        checked:
          type: boolean
      required:
        - id
        - richText
        - checked
      additionalProperties: false
  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:defects: Read defects
            read:photos: Read photos and photo folders
            write:photos: Create, update, delete, and sync photos and photo folders
            read:site_access: Read worker-project site access grants (explicitly approved pilot)
            write:sign_on_events: >-
              Record worker sign-on and sign-off events (explicitly approved
              pilot)

````