---
title: "Create a work order"
method: POST
path: "/v1/location/{location_id}/work_order"
tags: ["Work orders"]
---

# Create a work order

`POST /v1/location/{location_id}/work_order`

## Request

- Base URL: `https://api.navigateai.co`
- URL: `https://api.navigateai.co/v1/location/{location_id}/work_order`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/navigate/apis/navigateai-api/docs/v1/location/:location_id/work_order/post.ts> (a function with typed inputs; its response is checked against the schema)

## Path parameters

- `location_id` string, required

## Request body

- CreateWorkOrderRequest
  - `reference_key` string, required
  - `default_vendor_id` string, nullable: ID of the vendor to assign as the default for this work order.
  - `line_item_ids` string[], nullable: Line item IDs to attach. Must belong to a completed scope and not already be assigned to a different work order.

## Response `201`

Created

- WorkOrderResponse
  - `work_order` WorkOrderExternalSchema, required
    - `id` string, required
    - `status` 'open' | 'processing' | 'in_review' | 'reviewed' | 'completed', required
    - `reference_key` string, nullable, required: Optional unique identifier for this work order in your system.
    - `location_id` string, required
    - `review_url` string, required: Link to the NavigateAI dashboard for reviewing this work order.
    - `default_vendor` VendorOrganizationExternalSchema, required
      - `id` string, required
      - `name` string, required
      - `email` string, nullable, required
      - `reference_key` string, required: Optional unique identifier for this vendor in your system.
      - `is_enabled` boolean, required: Whether this vendor is enabled.
      - `market_ids` string[], required: IDs of the markets this vendor serves. A vendor with no market associations serves all markets.
    - `line_items` LineItemRowExternalSchema[], required: Location-level line items attached to this work order.
      - `id` string, required
      - `line_item_row_id` string, required: The stable location-level line item ID.
      - `title` string, required
      - `description` string, required
      - `status` 'suggested' | 'not_complete' | 'in_progress' | 'complete' | 'rejected', required
      - `quantity` integer, required: Deprecated: Use cost_components instead. Total quantity (integer).
      - `unit_type` string, required: Deprecated: Use cost_components instead. Unit of measurement (e.g. "each", "sqft").
      - `unit_cost_cents` integer, nullable, required: Deprecated: Use cost_components instead. Cost per unit in cents.
      - `cost_components` CostComponentExternalSchema[], required: Granular cost breakdown. Replaces the legacy quantity/unit_type/unit_cost_cents fields.
        - `kind` 'total' | 'labor' | 'material', required: The type of cost component: "total", "labor", or "material".
        - `label` string, nullable: Optional display label for this component.
        - `unit_type` string, nullable: Unit of measurement (e.g. "each", "sqft"). Defaults to "each" if omitted.
        - `unit_cost_in_cents` integer, nullable: Cost per unit in cents.
        - `quantity` string, required: Number of units as a decimal string (e.g. "1", "2.5").
      - `price_override_reason` string, nullable: The reason recorded when a cost component's price was overridden (e.g. a labor cost change), if a reason was provided. Reflects the most recent price override. Null when no reason was recorded.
      - `price_reference_key` string, nullable, required: Your external identifier for the pricing item used.
      - `notes` string, required
      - `custom_fields` object, required
      - `evidence` union[], required: Supporting evidence — images, audio segments, or text notes.
        - union
          - ImageEvidenceExternalSchema
            - `type` 'image'
            - `image_id` string, required: Use with the Get Image endpoint to retrieve the image file.
            - `reference_key` string, nullable: For an image from Upload an image, the `reference_key` you sent. Images captured in the NavigateAI app can have a value that the app set.
            - `visit_id` string, nullable: The visit this image was captured during. Null for images from Upload an image.
            - `is_selected` boolean: Whether this image was explicitly selected as evidence.
            - `is_starred` boolean: Whether this image was starred as the primary evidence photo.
          - AudioEvidenceExternalSchema
            - `type` 'audio'
            - `start_ms` integer, required: Start timestamp in the source video, in milliseconds.
            - `end_ms` integer, required: End timestamp in the source video, in milliseconds.
            - `text` string, required: Transcribed text from this audio segment.
            - `visit_id` string, nullable: The visit this audio was recorded during. Null when the evidence item is not tied to a visit.
          - TextEvidenceExternalSchema
            - `type` 'text'
            - `text` string, required
            - `visit_id` string, nullable: The visit this text was recorded during. Null when the answer is not tied to a visit.
      - `area_name` string, nullable, required: Deprecated: Use room.name instead. The room or area this line item applies to.
      - `room` LineItemRoomExternalSchema, required: The room or area a line item applies to.
        - `id` string, nullable, required: The [room](/api-reference/rooms/room-object) ID. Null when the room is not currently one of the location's rooms, for example before the visit that recorded it is reviewed, or after the room is removed.
        - `name` string, required: Display name of the room or area (e.g. 'Bedroom 2', 'Kitchen'). Not guaranteed to be stable over time.
        - `room_type_id` string, nullable: The [room type](/api-reference/room-types/room-type-object) ID.
      - `rejection_reason_option_id` string, nullable: ID of the selected [rejection reason option](/api-reference/rejection-reason-options/rejection-reason-option-object), if applicable.
      - `rejection_reason_text` string, nullable: Reason the line item was rejected, if applicable.
      - `vendor` VendorOrganizationExternalSchema
        - `id` string, required
        - `name` string, required
        - `email` string, nullable, required
        - `reference_key` string, required: Optional unique identifier for this vendor in your system.
        - `is_enabled` boolean, required: Whether this vendor is enabled.
        - `market_ids` string[], required: IDs of the markets this vendor serves. A vendor with no market associations serves all markets.
      - `policy_justifications` LineItemPolicyJustificationExternalSchema[], required: Policies this line item was evaluated against, with the reasoning for each, most relevant first. Empty when there are no policy justifications for this line item.
        - `policy` LineItemPolicyExternalSchema, required: A policy a line item was evaluated against.
          - `title` string, required: The title of the policy the line item was evaluated against.
        - `alignment` 'supports' | 'violates' | 'relates', required: Whether the line item supports, violates, or relates to the policy.
        - `reason` string, required: The reasoning for the alignment.
    - `latest_line_item_row_proposals` LineItemRowProposalExternalSchema[], required: The most recent visit-level observations for each line item.
      - `id` string, required
      - `line_item_row_id` string, required: The stable location-level line item ID.
      - `title` string, required
      - `description` string, required
      - `status` 'suggested' | 'not_complete' | 'in_progress' | 'complete' | 'rejected', required
      - `quantity` integer, required: Deprecated: Use cost_components instead. Total quantity (integer).
      - `unit_type` string, required: Deprecated: Use cost_components instead. Unit of measurement (e.g. "each", "sqft").
      - `unit_cost_cents` integer, nullable, required: Deprecated: Use cost_components instead. Cost per unit in cents.
      - `cost_components` CostComponentExternalSchema[], required: Granular cost breakdown. Replaces the legacy quantity/unit_type/unit_cost_cents fields.
        - `kind` 'total' | 'labor' | 'material', required: The type of cost component: "total", "labor", or "material".
        - `label` string, nullable: Optional display label for this component.
        - `unit_type` string, nullable: Unit of measurement (e.g. "each", "sqft"). Defaults to "each" if omitted.
        - `unit_cost_in_cents` integer, nullable: Cost per unit in cents.
        - `quantity` string, required: Number of units as a decimal string (e.g. "1", "2.5").
      - `price_override_reason` string, nullable: The reason recorded when a cost component's price was overridden (e.g. a labor cost change), if a reason was provided. Reflects the most recent price override. Null when no reason was recorded.
      - `price_reference_key` string, nullable, required: Your external identifier for the pricing item used.
      - `notes` string, required
      - `custom_fields` object, required
      - `evidence` union[], required: Supporting evidence — images, audio segments, or text notes.
        - union
          - ImageEvidenceExternalSchema
            - `type` 'image'
            - `image_id` string, required: Use with the Get Image endpoint to retrieve the image file.
            - `reference_key` string, nullable: For an image from Upload an image, the `reference_key` you sent. Images captured in the NavigateAI app can have a value that the app set.
            - `visit_id` string, nullable: The visit this image was captured during. Null for images from Upload an image.
            - `is_selected` boolean: Whether this image was explicitly selected as evidence.
            - `is_starred` boolean: Whether this image was starred as the primary evidence photo.
          - AudioEvidenceExternalSchema
            - `type` 'audio'
            - `start_ms` integer, required: Start timestamp in the source video, in milliseconds.
            - `end_ms` integer, required: End timestamp in the source video, in milliseconds.
            - `text` string, required: Transcribed text from this audio segment.
            - `visit_id` string, nullable: The visit this audio was recorded during. Null when the evidence item is not tied to a visit.
          - TextEvidenceExternalSchema
            - `type` 'text'
            - `text` string, required
            - `visit_id` string, nullable: The visit this text was recorded during. Null when the answer is not tied to a visit.
      - `area_name` string, nullable, required: Deprecated: Use room.name instead. The room or area this line item applies to.
      - `room` LineItemRoomExternalSchema, required: The room or area a line item applies to.
        - `id` string, nullable, required: The [room](/api-reference/rooms/room-object) ID. Null when the room is not currently one of the location's rooms, for example before the visit that recorded it is reviewed, or after the room is removed.
        - `name` string, required: Display name of the room or area (e.g. 'Bedroom 2', 'Kitchen'). Not guaranteed to be stable over time.
        - `room_type_id` string, nullable: The [room type](/api-reference/room-types/room-type-object) ID.
      - `rejection_reason_option_id` string, nullable: ID of the selected [rejection reason option](/api-reference/rejection-reason-options/rejection-reason-option-object), if applicable.
      - `rejection_reason_text` string, nullable: Reason the line item was rejected, if applicable.
      - `vendor` VendorOrganizationExternalSchema
        - `id` string, required
        - `name` string, required
        - `email` string, nullable, required
        - `reference_key` string, required: Optional unique identifier for this vendor in your system.
        - `is_enabled` boolean, required: Whether this vendor is enabled.
        - `market_ids` string[], required: IDs of the markets this vendor serves. A vendor with no market associations serves all markets.
      - `visit_id` string, required: The visit that produced this proposal.
      - `vendor_status_override` LineItemEditVendorStatusOverrideExternalSchema, required
        - `status` 'suggested' | 'not_complete' | 'complete' | 'canceled' | 'deleted' | 'ignored' | 'not_started' | 'in_progress', nullable, required: The vendor's claimed status for this line item.
        - `edit_justification` string, nullable, required: The vendor's reason for the status override.

## Changes

- **2026-10-14** `bbdde99b5256`: 2 info
  - added the required property `work_order/latest_line_item_row_proposals/items/room/anyOf[subschema #1: LineItemRoom]/id` to the response with the `201` status
  - added the required property `work_order/line_items/items/room/anyOf[subschema #1: LineItemRoom]/id` to the response with the `201` status
- **2026-09-23** `d184e670d61f`: 2 warning, 4 info
  - added the new `in_progress` enum value to the `work_order/latest_line_item_row_proposals/items/status` response property for the response status `201`
  - added the new `in_progress` enum value to the `work_order/line_items/items/status` response property for the response status `201`
  - added the optional property `work_order/latest_line_item_row_proposals/items/evidence/items/anyOf[subschema #2: AudioEvidence]/visit_id` to the response with the `201` status
  - added the optional property `work_order/latest_line_item_row_proposals/items/evidence/items/anyOf[subschema #3: TextEvidence]/visit_id` to the response with the `201` status
  - …2 more

[Operation history](https://skmtc.dev/navigate/apis/navigateai-api/changes/v1/location/:location_id/work_order/post.md)

---

[API](https://skmtc.dev/navigate/apis/navigateai-api.md) - [All operations](https://skmtc.dev/navigate/apis/navigateai-api/llms.txt) - [OpenAPI document](https://skmtc.dev/navigate/apis/navigateai-api/revisions/912b48581de7?raw)
