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

# Update Order

> Update a native **agentic** order. Supports external order identifiers, status, currency, country, totalAmount, shippingFee, discountAmount, metadata, orderCreatedAt, and line-item upserts (externalOrderItemId, price / unitPrice / paidPrice / costPrice / currency / status / quantity). Matching externalOrderItemId updates a line; a new externalOrderItemId with productName + quantity inserts a line (multi-SKU append). When totalAmount is omitted and lines change, the order total is recomputed from all lines. When country is omitted and stored country is empty, Omni derives country from the resulting order currency when unambiguous. Requires `orders:write`. Marketplace orders (Shopee, Lazada, TikTok, Shopify) are rejected with HTTP 409 — those fields are marketplace-owned. Emits `order.status.changed` when status changes and `order.updated` for other field changes.



## OpenAPI

````yaml /openapi.json patch /api/v1/orders/{orderId}
openapi: 3.1.0
info:
  title: OmniCommerce API
  version: 1.0.0
  license:
    name: Proprietary
    url: https://omnicommerce.sg/terms
  description: >-
    OmniCommerce API surface for agents and developer integrations. Includes
    public endpoints (merchant discovery, product search, compare, catalog, ACO
    retrieval) and authenticated endpoints (product management via API key
    Bearer tokens).
servers:
  - url: https://omnicommerce.sg
    description: Production
  - url: http://localhost:3000
    description: Local development
security: []
tags:
  - name: agentic-checkout
    description: Merchant-fulfilled agentic checkout
    x-group: Agentic Checkout
  - name: commerce
    description: Root commerce discovery
    x-group: Commerce
  - name: developer-platform
    description: Authenticated developer platform APIs
    x-group: Developer Platform
  - name: looks
    description: AI-styled product looks
    x-group: Looks
  - name: oauth
    description: OAuth token endpoints
    x-group: OAuth
  - name: orders
    description: Workspace and agentic orders
    x-group: Orders
  - name: organizations
    description: Organization management
    x-group: Organizations
  - name: price-books
    description: Marketplace list-price markup rules
    x-group: Price Books
  - name: products
    description: Product CRUD, bulk import, and publish
    x-group: Products
  - name: promotions
    description: Central promotions and marketplace sync
    x-group: Promotions
  - name: public-agent
    description: Public agent discovery and catalog APIs
    x-group: Public Agent
  - name: settlements
    description: settlements
    x-group: Settlements
  - name: ucp
    description: Universal Commerce Protocol
    x-group: UCP
paths:
  /api/v1/orders/{orderId}:
    patch:
      tags:
        - orders
      summary: Update Order
      description: >-
        Update a native **agentic** order. Supports external order identifiers,
        status, currency, country, totalAmount, shippingFee, discountAmount,
        metadata, orderCreatedAt, and line-item upserts (externalOrderItemId,
        price / unitPrice / paidPrice / costPrice / currency / status /
        quantity). Matching externalOrderItemId updates a line; a new
        externalOrderItemId with productName + quantity inserts a line
        (multi-SKU append). When totalAmount is omitted and lines change, the
        order total is recomputed from all lines. When country is omitted and
        stored country is empty, Omni derives country from the resulting order
        currency when unambiguous. Requires `orders:write`. Marketplace orders
        (Shopee, Lazada, TikTok, Shopify) are rejected with HTTP 409 — those
        fields are marketplace-owned. Emits `order.status.changed` when status
        changes and `order.updated` for other field changes.
      operationId: patch_v1_orders_by_orderid
      parameters:
        - name: orderId
          in: path
          required: true
          description: OmniCommerce order UUID returned from create or list.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              description: >-
                At least one of externalOrderId, externalOrderNumber, status,
                currency, country, totalAmount, shippingFee, discountAmount,
                metadata, orderCreatedAt, or items is required.
              properties:
                organizationId:
                  type: string
                  maxLength: 120
                  description: >-
                    Optional for OAuth clients bound to one organization;
                    required when the caller can access multiple organizations.
                externalOrderId:
                  type: string
                  maxLength: 160
                  description: >-
                    Replacement stable external order identifier. Must be unique
                    among agentic orders in the organization.
                externalOrderNumber:
                  type: string
                  maxLength: 160
                  description: Replacement customer-facing external order number.
                status:
                  type: string
                  enum:
                    - pending
                    - to_ship
                    - shipped
                    - completed
                    - return
                    - canceled
                  description: >-
                    Canonical order status: pending, to_ship, shipped,
                    completed, return, canceled.
                currency:
                  type: string
                  minLength: 3
                  maxLength: 3
                  description: >-
                    ISO-4217 currency code for the order. When country is empty,
                    unambiguous market currencies also derive country (see
                    country field).
                country:
                  type: string
                  maxLength: 80
                  description: >-
                    Marketplace country (code or name). Optional. When omitted
                    and the order's stored country is empty, Omni derives from
                    the resulting order currency when unambiguous
                    (SGD→singapore, MYR→malaysia, PHP→philippines, HKD→hong
                    kong, etc.). Explicit country always wins. USD is not used
                    to derive country.
                totalAmount:
                  type: number
                  minimum: 0
                  description: >-
                    Order total. When omitted and line prices change, recomputed
                    from line paid/unit prices × quantity.
                shippingFee:
                  type: number
                  minimum: 0
                discountAmount:
                  type: number
                  minimum: 0
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    Optional shallow merge into existing order metadata (does
                    not replace the full object).
                orderCreatedAt:
                  type: string
                  format: date-time
                  description: >-
                    Replacement order created timestamp (ISO 8601 with
                    timezone). Overwrites stored order_created_at used by
                    listing and analytics date filters. Omitted value is left
                    unchanged. Re-posting POST /api/v1/orders with the same
                    externalOrderId does not overwrite an existing created date.
                items:
                  type: array
                  minItems: 1
                  maxItems: 100
                  description: >-
                    Line upserts. Match by externalOrderItemId or productId to
                    update. To replace a line identifier, select with
                    currentExternalOrderItemId and provide the new
                    externalOrderItemId. To append a multi-SKU line, send a new
                    externalOrderItemId with productName and quantity.
                  items:
                    type: object
                    additionalProperties: false
                    properties:
                      currentExternalOrderItemId:
                        type: string
                        maxLength: 160
                        description: >-
                          Current line identifier used to select the line when
                          replacing externalOrderItemId.
                      externalOrderItemId:
                        type: string
                        maxLength: 160
                        description: >-
                          Selects the line when currentExternalOrderItemId is
                          omitted. When currentExternalOrderItemId is provided,
                          this is the replacement identifier. If no line matches
                          and productName + quantity are provided, inserts a new
                          line.
                      productId:
                        type: string
                        format: uuid
                        description: >-
                          Match a single line by product UUID when unique on the
                          order.
                      productName:
                        type: string
                        minLength: 1
                        maxLength: 500
                        description: Required with quantity when inserting a new line.
                      sku:
                        type: string
                        maxLength: 160
                      sellerSku:
                        type: string
                        maxLength: 160
                      shopSku:
                        type: string
                        maxLength: 160
                      quantity:
                        type: integer
                        minimum: 1
                        maximum: 9999
                        description: Required with productName when inserting a new line.
                      price:
                        type: number
                        minimum: 0
                        description: >-
                          Alias for `unitPrice` (list / original unit price).
                          Prefer `unitPrice` on new integrations.
                      unitPrice:
                        type: number
                        minimum: 0
                        description: >-
                          Per-unit list / original (sticker) price before line
                          discounts. Same meaning as `price`.
                      paidPrice:
                        type: number
                        minimum: 0
                        description: >-
                          Per-unit amount actually charged after discounts.
                          Preferred for totals and return refund estimates
                          (paidPrice×quantity when set, else
                          unitPrice/price×quantity). Not COGS.
                      costPrice:
                        type: number
                        minimum: 0
                        description: >-
                          Unit COGS. With productId (on the patch or existing
                          line), upserts product_data.costPrice. Omitted
                          costPrice never clears existing product or line cost.
                          Distinct from price/unitPrice/paidPrice. Stored in the
                          local/target currency after FX when costPriceCurrency
                          is set.
                      costPriceCurrency:
                        type: string
                        minLength: 3
                        maxLength: 3
                        description: >-
                          ISO currency of the raw costPrice (e.g. USD) before
                          conversion. Required when cost is not already in the
                          order/line currency. Alias: costCurrency.
                      costCurrency:
                        type: string
                        minLength: 3
                        maxLength: 3
                        description: Alias for costPriceCurrency.
                      costPriceFxRate:
                        type: number
                        exclusiveMinimum: 0
                        description: >-
                          Manual FX rate: units of costPriceFxTo per 1 unit of
                          costPriceCurrency (USD→MYR at 4.45 means 1 USD = 4.45
                          MYR). Omit to auto-fetch the rate from Frankfurter
                          (ECB daily rates).
                      costPriceFxTo:
                        type: string
                        minLength: 3
                        maxLength: 3
                        description: >-
                          Target currency for the conversion. Defaults to the
                          line currency, then the order currency, and must match
                          that accounting currency when one is present.
                      costPriceFxAsOf:
                        type: string
                        pattern: ^\d{4}-\d{2}(-\d{2})?$
                        description: >-
                          Pins the auto-fetched rate to a date: YYYY-MM-DD, or
                          YYYY-MM for the last calendar day of that month. Omit
                          to use the latest rate.
                      currency:
                        type: string
                        minLength: 3
                        maxLength: 3
                      status:
                        type: string
                        enum:
                          - pending
                          - to_ship
                          - shipped
                          - completed
                          - return
                          - canceled
                      imageUrl:
                        type: string
                        format: uri
                        maxLength: 2048
                      variation:
                        type: string
                        maxLength: 500
                      metadata:
                        type: object
                        additionalProperties: true
            examples:
              updateStatusAndLine:
                summary: Status, money, and line price patch
                value:
                  organizationId: org_123
                  externalOrderId: MY-223347629SG
                  externalOrderNumber: MY-223347629SG
                  status: shipped
                  currency: SGD
                  totalAmount: 120.5
                  items:
                    - currentExternalOrderItemId: dev-order-1
                      externalOrderItemId: '10817558'
                      price: 110
                      costPrice: 45
                      currency: SGD
                  metadata:
                    trackingNumber: SG123456789
              correctCreatedAt:
                summary: Correct the order created timestamp
                value:
                  organizationId: org_123
                  orderCreatedAt: '2026-03-15T08:00:00.000Z'
              appendMultiSkuLine:
                summary: Append a multi-SKU line on an existing agentic order
                description: >-
                  New externalOrderItemId with productName + quantity inserts a
                  line. Omit totalAmount so Omni recomputes from all lines.
                value:
                  organizationId: org_123
                  items:
                    - externalOrderItemId: ORD-9002
                      productName: Item B
                      sku: SKU-B
                      sellerSku: SKU-B
                      quantity: 1
                      paidPrice: 40
                      currency: SGD
      responses:
        '200':
          description: Order updated (or unchanged no-op).
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Bad Request — invalid status or payload
        '401':
          description: Unauthorized
        '403':
          description: Forbidden or missing `orders:write` scope
        '404':
          description: Order not found for this organization
        '409':
          description: >-
            Updates are not supported for marketplace-owned orders, or an
            external identifier is already in use
        '429':
          description: Rate limit exceeded
        '500':
          description: Internal Server Error
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >-
        Bearer API key for server-to-server access. Session auth is also
        supported in first-party UI flows.

````