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

# Cancel a visit and remove its assignments

> Company-scoped scheduling write available to every valid API key. Requires Idempotency-Key; retries with the same caller, key and parsed request return the committed visit without repeating the change or customer notification. Reusing a key with different input returns 409. Updates require expected_revision from the schedule visit read. Omitted or null customer_notification sends nothing. Explicit notifications use the selected account contact primary channel. Notification failure does not roll back scheduling; UNKNOWN may have reached the provider and is never automatically resent. SUPPRESSED means the visit revision or recipient eligibility changed before delivery. Write timestamps support at most six fractional digits; UUIDs are case-insensitive. Assignment changes preserve the arrival window unless explicitly updated. Outside-window work requires allow_outside_window=true. No availability or double-booking guarantee. Active/completed assignment changes return 409. See the scheduling guide for replacement arrays, reminders and deferred workflows.



## OpenAPI

````yaml /openapi.json post /job-appointments/{id}/cancel
openapi: 3.0.3
info:
  title: Breezy Public API
  version: 1.0.0
  description: >-
    Read customers, team members, jobs, visits, assignments, installed
    equipment, captured form responses, time entries, configured-period
    timesheets, business reference catalogs, job leads, estimates, invoices,
    payments, refunds, recorded job financials, saved sold/earned credits, and
    financial summaries for your company. Read the operational schedule and
    create, edit, cancel and assign visits. Existing API keys grant company-wide
    reads and scheduling writes. Customer notifications require an explicit
    request per operation. Amounts are integer USD cents. Reads return current
    corrected records, with cursor pagination for collecting results.


    Read the [Breezy FSM guides](https://developers.getbreezyapp.com) for
    authentication, pagination, refresh limits, and business measures. All reads
    use latest corrected company records; cursors do not create a snapshot or a
    complete change feed.
servers:
  - url: https://api.getbreezyapp.com/v1
    description: Breezy FSM production API
security:
  - apiKey: []
tags:
  - name: Scheduling
  - name: Company
  - name: Invoices
  - name: Payments
  - name: Refunds
  - name: Reports
  - name: TeamMembers
  - name: Accounts
  - name: Contacts
  - name: Locations
  - name: Jobs
  - name: JobAppointments
  - name: JobAssignments
  - name: BusinessUnits
  - name: JobTypes
  - name: JobClasses
  - name: JobLifecycles
  - name: LeadSources
  - name: Tags
  - name: Estimates
  - name: JobLeads
  - name: Equipment
  - name: FormResponses
  - name: TimeEntries
  - name: Timesheets
  - name: JobFinancials
  - name: RevenueAttributions
externalDocs:
  description: Breezy FSM reporting guides and API reference
  url: https://developers.getbreezyapp.com
paths:
  /job-appointments/{id}/cancel:
    post:
      tags:
        - Scheduling
      summary: Cancel a visit and remove its assignments
      description: >-
        Company-scoped scheduling write available to every valid API key.
        Requires Idempotency-Key; retries with the same caller, key and parsed
        request return the committed visit without repeating the change or
        customer notification. Reusing a key with different input returns 409.
        Updates require expected_revision from the schedule visit read. Omitted
        or null customer_notification sends nothing. Explicit notifications use
        the selected account contact primary channel. Notification failure does
        not roll back scheduling; UNKNOWN may have reached the provider and is
        never automatically resent. SUPPRESSED means the visit revision or
        recipient eligibility changed before delivery. Write timestamps support
        at most six fractional digits; UUIDs are case-insensitive. Assignment
        changes preserve the arrival window unless explicitly updated.
        Outside-window work requires allow_outside_window=true. No availability
        or double-booking guarantee. Active/completed assignment changes return
        409. See the scheduling guide for replacement arrays, reminders and
        deferred workflows.
      operationId: cancelJobAppointment
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            pattern: ^[A-Za-z0-9_-]{8,128}$
          required: true
          name: Idempotency-Key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancelAppointment'
            example:
              expected_revision: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
              reason: Need to Reschedule
              note: Customer away this week
      responses:
        '200':
          description: >-
            Committed visit and notification outcome. Replays retain the
            original visit snapshot; reread for current state.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduleMutationResponse'
              example:
                data:
                  id: 11111111-1111-4111-8111-000000001109
                  number: '300'
                  job_id: 11111111-1111-4111-8111-000000000501
                  type: Other
                  description: Air conditioner repair visit
                  window_start_at: '2026-09-08T19:00:00Z'
                  window_end_at: '2026-09-08T21:00:00Z'
                  confirmed: false
                  canceled: true
                  cancellation_reason: Need to Reschedule
                  cancellation_note: Customer away this week
                  created_by:
                    id: 11111111-1111-4111-8111-000000000401
                    name: Alex Example
                  created_at: '2026-08-19T16:00:00Z'
                  updated_at: '2026-09-08T19:00:00Z'
                  kind: APPOINTMENT
                  starts_at: '2026-09-08T19:00:00Z'
                  ends_at: '2026-09-08T21:00:00Z'
                  revision: >-
                    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                  job:
                    id: 11111111-1111-4111-8111-000000000501
                    number: '200'
                    summary: Repair air conditioner
                    account:
                      id: 11111111-1111-4111-8111-000000000101
                      name: Example Household
                    location:
                      id: 11111111-1111-4111-8111-000000001107
                      name: Home
                      address: 123 Example Lane, Los Angeles, CA 90001
                      latitude: 34.02
                      longitude: -118.25
                    contact:
                      id: 11111111-1111-4111-8111-000000001101
                      name: Jordan Example
                    business_unit:
                      id: 11111111-1111-4111-8111-000000000201
                      name: Service
                    job_type:
                      id: 11111111-1111-4111-8111-000000000301
                      name: HVAC Service
                    job_class: SERVICE
                  assignments: []
                  dispatch_status: CANCELED
                notification:
                  status: NOT_REQUESTED
                meta:
                  request_id: 11111111-1111-4111-8111-000000009999
                  generated_at: '2026-09-08T19:00:00Z'
                  timezone: America/Los_Angeles
        '400':
          description: >-
            Malformed input, unknown query parameter, unsupported combination or
            invalid cursor.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: INVALID_REQUEST
                  message: end_date must be later than start_date
                  request_id: example-request
                  details: []
        '401':
          description: Missing, invalid or expired key, or invalid linked identity.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
            WWW-Authenticate:
              schema:
                type: string
              example: Bearer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: UNAUTHENTICATED
                  message: A valid API key is required
                  request_id: example-request
                  details: []
        '404':
          description: >-
            Missing resource or resource outside the authenticated company. Same
            response for both.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: NOT_FOUND
                  message: Resource not found
                  request_id: example-request
                  details: []
        '405':
          description: >-
            Unsupported methods return 405. See the operation list for supported
            scheduling writes.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
            Allow:
              schema:
                type: string
              example: GET, HEAD, OPTIONS
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: METHOD_NOT_ALLOWED
                  message: This resource supports GET
                  request_id: example-request
                  details: []
        '409':
          description: >-
            Stale revision, idempotency-key reuse with different input,
            scheduling conflict, or unsupported stored recurrence. Inspect
            error.code.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: STALE_REVISION
                  message: The visit changed; read it again before editing
                  request_id: example-request
                  details: []
        '413':
          description: Request body is too large.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: INVALID_REQUEST
                  message: Request body exceeds 64 KB
                  request_id: example-request
                  details: []
        '429':
          description: Company request budget exhausted; retry after the indicated delay.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
              description: Seconds before retrying.
              example: 30
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: RATE_LIMITED
                  message: Request limit exceeded
                  request_id: example-request
                  details: []
        '500':
          description: >-
            Unexpected failure. Share request_id with support; no stack or
            provider secrets in response.
          headers:
            Cache-Control:
              schema:
                type: string
              example: private, no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: INTERNAL_ERROR
                  message: Unable to complete request
                  request_id: example-request
                  details: []
      security:
        - apiKey: []
components:
  schemas:
    CancelAppointment:
      type: object
      properties:
        expected_revision:
          type: string
          pattern: ^[a-f0-9]{64}$
          description: >-
            Revision from the schedule visit read or previous successful
            command.
        customer_notification:
          type: object
          nullable: true
          properties:
            channel:
              type: string
              enum:
                - EMAIL
                - SMS
            contact_id:
              type: string
              format: uuid
          default: null
          required:
            - channel
            - contact_id
          additionalProperties: false
        reason:
          type: string
          minLength: 1
          maxLength: 200
        note:
          type: string
          nullable: true
          maxLength: 2000
          default: null
      required:
        - expected_revision
        - reason
      additionalProperties: false
    ScheduleMutationResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/ScheduleAppointment'
        notification:
          type: object
          properties:
            status:
              type: string
              enum:
                - NOT_REQUESTED
                - PENDING
                - SENT
                - UNKNOWN
                - SUPPRESSED
          required:
            - status
          description: >-
            The scheduling change is committed regardless of notification
            outcome. UNKNOWN may have reached the provider and is never
            automatically resent. SUPPRESSED means the visit or recipient
            changed before delivery.
        meta:
          $ref: '#/components/schemas/ResponseMeta'
      required:
        - data
        - notification
        - meta
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - INVALID_REQUEST
                - INVALID_CURSOR
                - SCHEDULE_TOO_LARGE
                - INVALID_SCHEDULE_EVENT
                - SCHEDULE_CONFLICT
                - STALE_REVISION
                - IDEMPOTENCY_CONFLICT
                - UNAUTHENTICATED
                - NOT_FOUND
                - METHOD_NOT_ALLOWED
                - RATE_LIMITED
                - INTERNAL_ERROR
            message:
              type: string
            request_id:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - field
                  - message
          required:
            - code
            - message
            - request_id
            - details
      required:
        - error
    ScheduleAppointment:
      allOf:
        - $ref: '#/components/schemas/JobAppointment'
        - type: object
          properties:
            kind:
              type: string
              enum:
                - APPOINTMENT
            starts_at:
              type: string
              format: date-time
              description: Earliest start of the arrival window and its assignments.
            ends_at:
              type: string
              format: date-time
              description: Latest end of the arrival window and its assignments.
            revision:
              type: string
              description: >-
                Opaque version of this visit and its complete assignments; use
                for conditional writes.
            job:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                number:
                  type: string
                summary:
                  type: string
                  nullable: true
                account:
                  $ref: '#/components/schemas/Reference'
                location:
                  type: object
                  nullable: true
                  properties:
                    id:
                      type: string
                      format: uuid
                    name:
                      type: string
                      nullable: true
                    address:
                      type: string
                      nullable: true
                    latitude:
                      type: number
                      nullable: true
                    longitude:
                      type: number
                      nullable: true
                  required:
                    - id
                    - name
                    - address
                    - latitude
                    - longitude
                contact:
                  $ref: '#/components/schemas/NullableReference'
                business_unit:
                  $ref: '#/components/schemas/NullableReference'
                job_type:
                  $ref: '#/components/schemas/NullableReference'
                job_class:
                  $ref: '#/components/schemas/NullableJobClass'
              required:
                - id
                - number
                - summary
                - account
                - location
                - contact
                - business_unit
                - job_type
                - job_class
            assignments:
              type: array
              items:
                $ref: '#/components/schemas/JobAssignment'
              description: >-
                Complete set of this visit's company-owned assignments,
                including outside the requested period or technician filter.
            dispatch_status:
              type: string
              enum:
                - CANCELED
                - UNASSIGNED
                - ASSIGNED
                - EN_ROUTE
                - IN_PROGRESS
                - COMPLETED
          required:
            - kind
            - starts_at
            - ends_at
            - revision
            - job
            - assignments
            - dispatch_status
    ResponseMeta:
      type: object
      properties:
        request_id:
          type: string
        generated_at:
          type: string
          format: date-time
        timezone:
          type: string
      required:
        - request_id
        - generated_at
        - timezone
      description: >-
        Generation time and company timezone. generated_at is not a snapshot or
        synchronization token.
    JobAppointment:
      type: object
      properties:
        id:
          type: string
          format: uuid
        number:
          type: string
        job_id:
          type: string
          format: uuid
        type:
          type: string
        description:
          type: string
          nullable: true
        window_start_at:
          type: string
          format: date-time
        window_end_at:
          type: string
          format: date-time
        confirmed:
          type: boolean
        canceled:
          type: boolean
        cancellation_reason:
          type: string
          nullable: true
        cancellation_note:
          type: string
          nullable: true
        created_by:
          $ref: '#/components/schemas/NullableReference'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
          description: >-
            Parent record edit time only; related records may change
            independently.
      required:
        - id
        - number
        - job_id
        - type
        - description
        - window_start_at
        - window_end_at
        - confirmed
        - canceled
        - cancellation_reason
        - cancellation_note
        - created_by
        - created_at
        - updated_at
    Reference:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
      required:
        - id
        - name
    NullableReference:
      type: object
      nullable: true
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
      required:
        - id
        - name
    NullableJobClass:
      type: string
      nullable: true
      enum:
        - SERVICE
        - MAINTENANCE
        - ESTIMATE_REPAIR
        - ESTIMATE_REPLACE
        - INSTALL
        - WARRANTY
        - CALLBACK
        - SALES
        - UNKNOWN
        - null
    JobAssignment:
      type: object
      properties:
        id:
          type: string
          format: uuid
        job_id:
          type: string
          format: uuid
        appointment_id:
          type: string
          format: uuid
        team_member:
          $ref: '#/components/schemas/Reference'
        starts_at:
          type: string
          format: date-time
        ends_at:
          type: string
          format: date-time
        status:
          type: string
          nullable: true
          enum:
            - TO_DO
            - EN_ROUTE
            - IN_PROGRESS
            - COMPLETED
            - CANCELED
            - null
        status_updated_at:
          type: string
          nullable: true
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          description: >-
            Unavailable: assignment edits do not maintain a parent update
            timestamp.
          nullable: true
          enum:
            - null
      required:
        - id
        - job_id
        - appointment_id
        - team_member
        - starts_at
        - ends_at
        - status
        - status_updated_at
        - created_at
        - updated_at
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        Existing Breezy API key. Grants all published reads and scheduling
        writes in its associated company. No app permission scopes.

````