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

# Record gate attendance (limited pilot)

> Report provider sign-on and sign-off events with durable retry identity.

<Warning>
  Deployed for a limited, explicitly approved pilot. Existing integrations do not
  receive `write:sign_on_events` automatically. The pairing contract below requires
  agreement with the provider before rollout; deployment does not establish
  controller integration or general availability.
</Warning>

## One physical event per request

Requires `write:sign_on_events`, a connected integrator and a worker-project
site-access relationship. Reports observed attendance; it never grants or
restores access. A revoked relationship still accepts historical attendance.

```json theme={null}
{
  "sourceEventId": "controller-event-100",
  "workerId": "wkr_clgbsb90b001qjy0f0eo1hspp",
  "type": "SIGN_ON",
  "occurredAt": "2026-09-15T01:00:00.000Z",
  "deviceId": "north-gate"
}
```

For sign-off, send a different stable event ID and explicitly reference the
source sign-on ID for that visit:

```json theme={null}
{
  "sourceEventId": "controller-event-101",
  "sourceSignOnEventId": "controller-event-100",
  "workerId": "wkr_clgbsb90b001qjy0f0eo1hspp",
  "type": "SIGN_OFF",
  "occurredAt": "2026-09-15T03:00:00.000Z",
  "deviceId": "north-gate"
}
```

Times must be UTC with millisecond precision or less and cannot be in the future.
Event/device IDs are at most 200 characters. Extra fields are rejected.

## Retries, conflicts and late delivery

* Event identity is scoped to integrator, builder and project, across credential rotation.
* Replaying the same ID and payload returns `200` with `duplicate: true`.
* Reusing an ID with different data returns `409` and changes nothing.
* A new applied event returns `201`. Sign-offs close only the explicitly referenced visit.
* A sign-off received first returns `202`, `PENDING_SIGN_ON` and a null attendance ID. It is stored durably and applied atomically when its sign-on arrives. Replay the sign-off to retrieve its current status.
* A reference to another worker, a sign-off before sign-on, or a second distinct sign-off for the same visit returns `409`.
* An already manually closed or archived attendance record returns `409`; provider retries do not overwrite administrator corrections.
* Retry network errors or server failures with the original event ID and payload. Treat payload/pairing conflicts as reconciliation work, not a reason to generate a fresh ID.

```json theme={null}
{
  "data": {
    "id": "saevt_example",
    "sourceEventId": "controller-event-101",
    "status": "APPLIED",
    "signOnId": "signon_example",
    "duplicate": false
  }
}
```

Events are audited and projected into integration-generated BuildPass attendance
records using the project's timezone for day grouping. This does not run the
interactive worker sign-on questionnaire, approve safety tasks, or establish
controller authorization. Worker-app state, evacuation workflows, notifications
and reporting acceptance must be verified before enabling a provider pilot. Rejected
attempts and visitors are not supported by this endpoint.


## OpenAPI

````yaml POST /builders/{builderId}/projects/{projectId}/sign-on-events
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}/projects/{projectId}/sign-on-events:
    post:
      summary: Record gate attendance (limited pilot)
      description: >-
        Deployed for an explicitly approved pilot. Requires write:sign_on_events
        and a connected integrator; existing integrations receive no new scope
        automatically. Records observed attendance without granting access. One
        event per request. Provider pairing agreement and controller acceptance
        remain separate rollout requirements.
      operationId: recordProjectSignOnEvent
      parameters:
        - name: builderId
          description: The ID of the builder
          in: path
          required: true
          schema:
            type: string
            example: buil_clgbsb90b001qjy0f0eo1hspp
        - name: projectId
          description: The ID of the project
          in: path
          required: true
          schema:
            type: string
            example: proj_clgbsb90b001qjy0f0eo1hspp
        - name: X-BuildPass-Api-Version
          in: header
          required: true
          schema:
            $ref: '#/components/schemas/X-BuildPass-Api-Version'
        - name: X-BuildPass-Region-Id
          in: header
          required: false
          description: Builder database region; defaults to au1.
          schema:
            type: string
            enum:
              - au1
              - us1
            default: au1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  additionalProperties: false
                  properties:
                    sourceEventId:
                      type: string
                      minLength: 1
                      maxLength: 200
                    workerId:
                      type: string
                      pattern: ^wkr_[a-zA-Z0-9]+$
                    type:
                      type: string
                      enum:
                        - SIGN_ON
                    occurredAt:
                      type: string
                      format: date-time
                      description: >-
                        UTC occurrence time, millisecond precision or less;
                        cannot be in the future.
                    deviceId:
                      type: string
                      minLength: 1
                      maxLength: 200
                  required:
                    - sourceEventId
                    - workerId
                    - type
                    - occurredAt
                - type: object
                  additionalProperties: false
                  properties:
                    sourceEventId:
                      type: string
                      minLength: 1
                      maxLength: 200
                    workerId:
                      type: string
                      pattern: ^wkr_[a-zA-Z0-9]+$
                    type:
                      type: string
                      enum:
                        - SIGN_OFF
                    occurredAt:
                      type: string
                      format: date-time
                      description: >-
                        UTC occurrence time, millisecond precision or less;
                        cannot be in the future.
                    sourceSignOnEventId:
                      type: string
                      minLength: 1
                      maxLength: 200
                      description: Required for SIGN_OFF; forbidden for SIGN_ON.
                    deviceId:
                      type: string
                      minLength: 1
                      maxLength: 200
                  required:
                    - sourceEventId
                    - workerId
                    - type
                    - occurredAt
                    - sourceSignOnEventId
      responses:
        '200':
          description: Identical event replay; current processing status returned.
        '201':
          description: New event applied to an attendance record.
        '202':
          description: Sign-off durably recorded, pending its referenced sign-on.
        '400':
          description: Invalid input or future timestamp.
        '401':
          description: Missing authorization or required write scope.
        '403':
          description: Disconnected integrator or builder mismatch.
        '404':
          description: Project or worker-site relationship not found.
        '409':
          description: >-
            Conflicting source event, sign-off pairing or concurrently modified
            attendance.
      security:
        - OAuth2:
            - write:sign_on_events
components:
  schemas:
    X-BuildPass-Api-Version:
      type: string
      example: v1
      default: v1
      enum:
        - v1
      description: What API version to use.
  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)

````