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

# Validate or apply a mass write

> Checks a mass write plan, or starts it as an operation that you poll until it finishes. Send `validateOnly` as `true` to check the plan without writing.

> [!WARNING]
>
> A real apply writes to live points through their connectors. There is no undo call. To release an override, send `priority` with the release option from the group `fields`, for example `auto`. Always validate first, check `summary.points`, and start with a small query.

A plan has a `query` and a list of `writes`. The `query` is the one you used in [Discover mass write point groups](https://docs.kodelabs.com/products/kode-api/api-reference/mass-write/discover-mass-write-point-groups.md). Each write lists `groupKeys` and `actions`. An action has an `id`, a field of the group, and a `value`. Every discovered group must be in exactly one write. Every action `id` must be a field of its groups. A value must fit the field `dataType`, and a `SELECT` field accepts only its `options`.

**Validate first**

With `validateOnly` set to `true`, the response holds `validationReport` and nothing is written. Read:

* `valid`: `true` when the plan has no issue.
* `summary`: How many points, groups, and writes the plan reaches, with counts of errors and warnings.
* `writes[]`: The outcome of each write, in request order, with its own `issues`.
* `issues`: Issues with the plan as a whole.
* `unmatchedGroups`: Groups that no write covers.
* `etag`: A fingerprint of the plan. It is present only when the plan is valid.

Each issue has a `code`, a `pointer` to the part of your request, and a `message`. The codes are `NO_MATCHING_POINTS`, `UNKNOWN_GROUP`, `DUPLICATE_WRITE`, `WRITES_INCOMPLETE`, and `INVALID_ACTION`. A validation lists every issue. A real apply stops with `400` on the first kind of issue.

**Start the write**

Send the same body without `validateOnly`, with a `requestId` of your choice and the `etag` from the report. The response holds `operation`. Keep the last segment of `operation.name` as the `operationId`, then poll [Get a mass write operation](https://docs.kodelabs.com/products/kode-api/api-reference/mass-write/get-a-mass-write-operation.md).

* The response is `200`, not `202`.
* Sending the same `requestId` with the same body within 24 hours returns the operation it already started. Sending it with a different body returns `400`.
* If the plan changed since you validated it, the `etag` no longer matches and the call returns `400`. Validate again to get a new `etag`.
* A building can have only one mass write running. A second apply returns `400` with "Another point mass write is running" until the first operation is finished. An operation finishes when you read it and every point has an outcome.

> [!NOTE]
>
> Your service account needs the permission to manage mass writes, including for a validation. Its role can also limit overrides. An override longer than the maximum duration returns `403`. An override longer than the reason threshold without a `reason` returns `400`. Names and reasons can have up to 255 characters, and `notes` up to 2,000.


## OpenAPI

````yaml /openapi/kode-api.yaml post /api/v1/mass-write/points:apply
openapi: 3.1.0
info:
  title: KODE API
  version: 1.0.0
  summary: Programmatic access to KODE OS resources and operations.
  description: >
    Use the KODE API to work with buildings, data sources, connectors, devices,
    points, virtual devices,

    timeseries data, schedules, the ontology, templating, mass writes, spaces,
    space assignments, tenants, meters, users, actions,

    and AssetOps work orders.
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://api.kodelabs.com/kodeos
    description: KODE API
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: OAuth 2.0 discovery, token, and revocation endpoints.
  - name: Buildings
    description: Buildings and their areas.
  - name: Data sources
    description: Data sources connected to a building.
  - name: Devices
    description: Devices and their points.
  - name: Points
    description: Point queries and point writes.
  - name: Timeseries
    description: Current and historical point values.
  - name: Actions
    description: Actions exposed by building data sources.
  - name: Work orders
    description: AssetOps work orders, lookups, comments, and attachments.
  - name: Connectors
    description: KODE API connectors and the devices and points ingested through them.
  - name: Schedules
    description: Schedules discovered on building data sources.
  - name: Templating
    description: Apply ontology templates to groups of points.
  - name: Virtual devices
    description: Virtual devices that group points from other devices.
  - name: Ontology
    description: Canonical types, fields, units, and connections of the KODE ontology.
  - name: Users
    description: Users of the organization and their app access.
  - name: Mass write
    description: Write values to many points across buildings, and follow each run.
  - name: Spaces
    description: Levels and space units of a building, and the meters located in them.
  - name: Space assignments
    description: Assign tenants to leasable spaces of a building for a period.
  - name: Tenants
    description: Tenants of a building, the people or companies that lease its spaces.
  - name: Meters
    description: >-
      Meters of a building, their space assignments, parent and child links, and
      readings.
paths:
  /api/v1/mass-write/points:apply:
    post:
      tags:
        - Mass write
      summary: Validate or apply a mass write
      description: >-
        Checks a mass write plan, or starts it as an operation that you poll
        until it finishes. Send `validateOnly` as `true` to check the plan
        without writing.
      operationId: applyMassWrite
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PointMassWriteApplyRequestBody'
        required: true
      responses:
        '200':
          description: >-
            The started operation in `operation`, or the validation report in
            `validationReport` when `validateOnly` is `true`. Exactly one of the
            two is present.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PointMassWriteApplyResultPublic'
        '400':
          description: >-
            The body is not valid, a building is not one of yours, the query
            matches more than 30,000 points, the plan has an issue, the `etag`
            is stale, the `requestId` was used for a different plan, or another
            mass write is running in the same buildings. For a plan issue, the
            `fields` list in the error names the part of the plan. Validate with
            `validateOnly` to see every issue.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            The service account lacks permission to manage mass writes, has no
            assigned building, or the role limits the override you sent.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          description: KODE could not load the write fields of the groups. Try again later.
components:
  schemas:
    PointMassWriteApplyRequestBody:
      type: object
      properties:
        validateOnly:
          description: >-
            Set to `true` to validate the plan and write nothing. The default is
            `false`, which starts the write.
          type: boolean
          examples:
            - false
        requestId:
          description: >-
            Your id for this write, up to 128 characters. Sending it again with
            the same body within 24 hours returns the operation it started.
          type: string
          examples:
            - 2b7e9c1a-aaa-2026-10-14
          pattern: '[^\p{C}\p{Z}]{1,128}'
          maxLength: 128
        etag:
          description: >-
            The `etag` from a validation report. The call fails with `400` if
            the plan has changed since.
          type: string
          examples:
            - sha256:9f86d0818...
          pattern: '[^\p{C}\p{Z}]{1,128}'
          maxLength: 128
        name:
          description: Name of the operation, up to 255 characters.
          type: string
          examples:
            - AAA
          pattern: (?s)(?=.*[^\p{C}\p{Z}])[\P{Cc}\n\r\t]*
          maxLength: 255
        reason:
          description: >-
            Why you are writing, up to 255 characters. A role can require a
            reason for longer overrides.
          type: string
          pattern: (?s)(?=.*[^\p{C}\p{Z}])[\P{Cc}\n\r\t]*
          maxLength: 255
        notes:
          description: Free text, up to 2,000 characters.
          type: string
          pattern: (?s)(?=.*[^\p{C}\p{Z}])[\P{Cc}\n\r\t]*
          maxLength: 2000
        query:
          $ref: '#/components/schemas/PointMassWriteQueryPublic'
          description: >-
            Selects the points to write. Use the same query you used to discover
            the groups.
          type: object
        writes:
          description: >-
            Each write sets actions on one or more groups. Every discovered
            group must be in exactly one write.
          type: array
          items:
            $ref: '#/components/schemas/PointMassWriteWritePublic'
          maxItems: 10000
      required:
        - query
    PointMassWriteApplyResultPublic:
      type: object
      properties:
        validationReport:
          $ref: '#/components/schemas/PointMassWriteValidationReportPublic'
          description: Present when `validateOnly` is `true`.
        operation:
          $ref: '#/components/schemas/PointMassWriteOperationPublic'
          description: Present when the write started.
    PointMassWriteQueryPublic:
      type: object
      required:
        - buildingIds
      properties:
        buildingIds:
          description: >-
            Buildings to search. From 1 to 1,000 ids, each up to 128 characters
            with no spaces. Required.
          type: array
          items:
            type: string
            pattern: '[^\p{C}\p{Z}]{1,128}'
            maxLength: 128
          maxItems: 1000
          minItems: 1
        canonicalTypes:
          description: Keep points on devices of these canonical types.
          type: array
          items:
            type: string
            maxLength: 255
            pattern: (?s)(?=.*[^\p{C}\p{Z}])[\P{Cc}\n\r\t]*
          examples:
            - - VAV
          maxItems: 100
        kinds:
          description: >-
            Keep points of these kinds. Use `Number`, `Bool`, or `Str`. The
            values are case-sensitive.
          type: array
          items:
            type: string
            pattern: Number|Bool|Str
          examples:
            - - Number
          maxItems: 3
        fields:
          description: Keep points that have one of these ontology fields.
          type: array
          items:
            type: string
            maxLength: 255
            pattern: (?s)(?=.*[^\p{C}\p{Z}])[\P{Cc}\n\r\t]*
          examples:
            - - Space Temp Setpoint
          maxItems: 500
        connectorTypes:
          description: Keep points from these connector types, for example `API_JACE`.
          type: array
          items:
            type: string
            maxLength: 255
            pattern: (?s)(?=.*[^\p{C}\p{Z}])[\P{Cc}\n\r\t]*
          examples:
            - - API_JACE
          maxItems: 100
        areaIds:
          description: Keep points in these areas.
          type: array
          items:
            type: string
            pattern: '[^\p{C}\p{Z}]{1,128}'
            maxLength: 128
          maxItems: 1000
        deviceIds:
          description: Keep points on these devices.
          type: array
          items:
            type: string
            pattern: '[^\p{C}\p{Z}]{1,128}'
            maxLength: 128
          maxItems: 2000
        nameContains:
          description: >-
            Keep points whose name contains this text. The match is not
            case-sensitive.
          type: string
          examples:
            - Zone
          pattern: (?s)(?=.*[^\p{C}\p{Z}])[\P{Cc}\n\r\t]*
          maxLength: 255
        excludePointIds:
          description: Leave out these points.
          type: array
          items:
            type: string
            pattern: '[^\p{C}\p{Z}]{1,128}'
            maxLength: 128
          maxItems: 5000
    PointMassWriteWritePublic:
      type: object
      required:
        - groupKeys
        - actions
      properties:
        groupKeys:
          description: Keys of the groups this write applies to.
          type: array
          items:
            type: string
            pattern: '[^\p{C}\p{Z}]{1,128}'
            maxLength: 128
          maxItems: 1000
          minItems: 1
        actions:
          description: Values to write. Each `id` is a field of the groups.
          type: array
          items:
            $ref: '#/components/schemas/PointMassWriteActionPublic'
          maxItems: 50
          minItems: 1
    PointMassWriteValidationReportPublic:
      type: object
      properties:
        valid:
          description: '`true` when the plan has no issue.'
          type: boolean
        etag:
          description: >-
            Fingerprint of the resolved plan. Present only when the plan is
            valid.
          type: string
          examples:
            - sha256:9f86d0818...
        summary:
          $ref: '#/components/schemas/Summary1'
          description: Size of the plan.
        writes:
          description: Result for each write, in request order.
          type: array
          items:
            $ref: '#/components/schemas/Write'
        issues:
          description: Issues with the plan as a whole.
          type: array
          items:
            $ref: '#/components/schemas/PointMassWriteIssuePublic'
        unmatchedGroups:
          description: Groups that no write covers.
          type: array
          items:
            $ref: '#/components/schemas/PointMassWriteGroupPublic'
    PointMassWriteOperationPublic:
      type: object
      properties:
        name:
          description: >-
            Resource name of the operation. The last segment is the
            `operationId`.
          type: string
          examples:
            - mass-write/operations/6acf8bcf8564cb8ad4ccf8f3
        done:
          description: Whether the operation has finished.
          type: boolean
        metadata:
          $ref: '#/components/schemas/Metadata2'
          description: Progress and identifying data. Always present.
        response:
          $ref: '#/components/schemas/Response'
          description: Outcome counts. Present when the state is `SUCCEEDED`.
        error:
          $ref: '#/components/schemas/Error'
          description: Present when the state is `FAILED`.
    PointMassWriteActionPublic:
      type: object
      required:
        - id
        - value
      properties:
        id:
          description: Field id from the group `fields`, for example `priority`.
          type: string
          examples:
            - priority
          pattern: '[^\p{C}\p{Z}]{1,128}'
          maxLength: 128
        value:
          description: >-
            Value to write. It must fit the field `dataType`. For a field with
            `options`, it must be one of them.
          examples:
            - override
    Summary1:
      type: object
      properties:
        scope:
          description: '`BUILDING` or `PORTFOLIO`.'
          type: string
        buildings:
          description: Buildings with matched points.
          type: integer
          format: int32
        points:
          description: Points the write would reach.
          type: integer
          format: int64
        groups:
          description: Groups found.
          type: integer
          format: int32
        writes:
          description: Writes in the plan.
          type: integer
          format: int32
        errors:
          description: Number of errors.
          type: integer
          format: int32
        warnings:
          description: Number of warnings.
          type: integer
          format: int32
    Write:
      type: object
      properties:
        index:
          description: Position of the write in `writes`, starting at `0`.
          type: integer
          format: int32
        groupKeys:
          description: Group keys of the write.
          type: array
          items:
            type: string
        matchedPoints:
          description: Points the write would reach.
          type: integer
          format: int32
        status:
          description: '`OK` or `ERROR`.'
          type: string
          examples:
            - OK
        issues:
          description: Issues with this write.
          type: array
          items:
            $ref: '#/components/schemas/PointMassWriteIssuePublic'
    PointMassWriteIssuePublic:
      type: object
      properties:
        code:
          description: >-
            Issue code: `NO_MATCHING_POINTS`, `UNKNOWN_GROUP`,
            `DUPLICATE_WRITE`, `WRITES_INCOMPLETE`, or `INVALID_ACTION`.
          type: string
          examples:
            - INVALID_ACTION
        pointer:
          description: >-
            Path to the part of your request that the issue concerns, for
            example `/writes/0/groupKeys/1`.
          type: string
          examples:
            - /writes/0/groupKeys/2
        message:
          description: What is wrong.
          type: string
          examples:
            - 'value: expected one of False, True'
    PointMassWriteGroupPublic:
      type: object
      properties:
        groupKey:
          description: >-
            Key of the group. Use it in `writes[].groupKeys`. The key is stable
            for the same points.
          type: string
          examples:
            - mw1.Yz3kR1a2B3c4D5e6F7g8H9
        kind:
          description: 'Kind of the points in the group: `Number`, `Bool`, or `Str`.'
          type: string
          examples:
            - Number
        connectorType:
          description: Connector type of the points, for example `API_JACE`.
          type: string
          examples:
            - API_JACE
        field:
          description: Ontology field of the points, when they have one.
          type: string
          examples:
            - Space Temp Setpoint
        templated:
          description: Whether the points in the group are templated.
          type: boolean
        unit:
          $ref: '#/components/schemas/PointMassWriteUnitPublic'
          description: Unit of the points. Set for `Number` groups.
          type: object
        pointEnum:
          description: Values of the points. Set for `Bool` and `Str` groups.
          type: array
          items:
            type: string
          examples:
            - - 'False'
              - 'True'
        points:
          description: Number of points in the group.
          type: integer
          format: int32
          examples:
            - 16
        fields:
          description: Fields a write to this group can carry.
          type: array
          items:
            $ref: '#/components/schemas/PointMassWriteFieldPublic'
    Metadata2:
      type: object
      properties:
        operation:
          description: Always `APPLY`.
          type: string
          examples:
            - APPLY
        state:
          description: '`QUEUED`, `RUNNING`, `SUCCEEDED`, or `FAILED`.'
          type: string
          examples:
            - RUNNING
        progress:
          description: Share of points with an outcome, as a percentage.
          type: number
          format: double
          examples:
            - 29.3
        label:
          description: The `name` you sent.
          type: string
        scope:
          description: '`BUILDING` or `PORTFOLIO`.'
          type: string
        buildings:
          description: Number of buildings in the operation.
          type: integer
          format: int32
        total:
          description: Number of points in the operation.
          type: integer
          format: int32
        counts:
          $ref: '#/components/schemas/Counts'
          description: Points by outcome. Present while the operation is not done.
          type: object
        retries:
          description: How many times the operation was retried.
          type: integer
          format: int32
        createdAt:
          $ref: '#/components/schemas/Date'
          description: When the operation was created.
        updatedAt:
          $ref: '#/components/schemas/Date'
          description: When the operation was last updated.
        finishedAt:
          $ref: '#/components/schemas/Date'
          description: When the operation finished. Empty until then.
        actorId:
          description: Id of the service account that started the operation.
          type: string
        actorType:
          description: Always `SERVICE`.
          type: string
        etag:
          description: Etag of the plan the operation started from.
          type: string
        requestId:
          description: The `requestId` the operation started with.
          type: string
        pollAfterSeconds:
          description: >-
            Seconds to wait before the next read. Present while the operation is
            not done.
          type: integer
          format: int32
          examples:
            - 15
    Response:
      type: object
      properties:
        total:
          description: Number of points.
          type: integer
          format: int32
        succeeded:
          description: Points written.
          type: integer
          format: int32
        failed:
          description: Points that failed.
          type: integer
          format: int32
        notes:
          description: Notices about the run.
          type: array
          items:
            type: string
    Error:
      type: object
      properties:
        code:
          description: '`INTERNAL_ERROR` or `TIMEOUT`.'
          type: string
          examples:
            - TIMEOUT
        message:
          description: What went wrong.
          type: string
    PointMassWriteUnitPublic:
      type: object
      properties:
        id:
          type: string
          examples:
            - fahrenheit
        symbol:
          type: string
          examples:
            - °F
    PointMassWriteFieldPublic:
      type: object
      properties:
        id:
          description: Action id. Use it as `actions[].id`.
          type: string
          examples:
            - priority
        name:
          description: Display name of the field.
          type: string
          examples:
            - Priority
        dataType:
          $ref: '#/components/schemas/MassWriteFieldType'
          description: >-
            Type of the value: `NUMBER`, `DURATION_MS` (milliseconds), or
            `STRING`.
          type: string
          examples:
            - STRING
        inputType:
          $ref: '#/components/schemas/MassWriteFieldInput'
          description: >-
            `SELECT` means the value must be one of `options`. `TEXT` means any
            text.
          type: string
        required:
          description: Whether a write to the group must carry this field.
          type: boolean
        requiredWhen:
          $ref: '#/components/schemas/RequiredWhen'
          description: Conditions under which the field becomes required.
          type: object
        options:
          description: Allowed values when `inputType` is `SELECT`.
          type: array
          items:
            $ref: '#/components/schemas/Option'
        unit:
          description: Unit symbol of the value.
          type: string
          examples:
            - °F
    Counts:
      type: object
      properties:
        pending:
          description: Points still waiting for an outcome.
          type: integer
          format: int32
        succeeded:
          description: Points written.
          type: integer
          format: int32
        failed:
          description: Points that failed.
          type: integer
          format: int32
    Date:
      type: string
      description: >-
        Date and time in UTC, with a numeric offset and no colon, for example
        `2026-10-28T13:51:31+0000`.
      examples:
        - 2026-10-28T13:51:31+0000
    MassWriteFieldType:
      type: string
      enum:
        - NUMBER
        - DURATION_MS
        - STRING
    MassWriteFieldInput:
      type: string
      enum:
        - SELECT
        - TEXT
    RequiredWhen:
      type: object
      properties:
        match:
          $ref: '#/components/schemas/Match'
          description: 'ALL: every condition holds; ANY: at least one does.'
          type: string
          examples:
            - ALL
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/Condition'
    Option:
      type: object
      properties:
        id:
          type: string
          description: Value to send.
          examples:
            - override
        name:
          type: string
          description: Display name.
          examples:
            - Override
    Match:
      type: string
      enum:
        - ALL
        - ANY
    Condition:
      type: object
      properties:
        fieldId:
          type: string
          description: Id of the action the condition reads.
          examples:
            - priority
        operator:
          $ref: '#/components/schemas/Operator1'
          description: >-
            IN: the action's value is one of values; EQUAL / NOT_EQUAL: compared
            with the first value; EXISTS: the action is given. ANY ignores
            NOT_EQUAL conditions.
          type: string
          examples:
            - IN
        values:
          type: array
          items:
            type: string
          examples:
            - - override
              - set
    Operator1:
      type: string
      enum:
        - IN
        - EQUAL
        - NOT_EQUAL
        - EXISTS
  responses:
    Unauthorized:
      description: The access token is missing, invalid, or expired. Request a new token.
    TooManyRequests:
      description: >-
        A rate-limit window is exhausted. Wait, then retry with increasing
        delays.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >
        Paste an access token from [Create an access
        token](/products/kode-api/api-reference/authentication/create-an-access-token).
        Tokens expire, so request a new one if you receive `401`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.