> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer-stage.shipbob.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer-stage.shipbob.dev/_mcp/server.

# Update Shipment Line Items


POST https://sandbox-api.shipbob.com/2026-01/shipment/{shipmentId}:updateLineItems
Content-Type: application/json

Updates the line items for a specific shipment. The request body must include the complete list of line items as returned by the GET /shipment/{shipmentId}:getLineItems endpoint — partial updates are not supported. Retrieve the current line items first, modify the desired fields, and submit the full payload.

**Important:** The `is_manually_assigned_lot` field must be set to the same value for all line items in the request. When set to `true` on any item, ShipBob treats all lot assignments in the shipment as manually reviewed — ShipBob will not auto-assign or re-optimize lots for any item. When set to `false`, ShipBob manages lot selection automatically. Mixing `true` and `false` across items in the same request will result in a validation error.

**Note on error handling:** This endpoint returns HTTP 200 for both successful and failed operations. Always check the `is_success` field in the response body to determine the outcome. When `is_success` is `false`, the `error` object contains the error code and message. HTTP 400 is only returned when the request body itself is missing or empty.


Reference: https://developer-stage.shipbob.dev/api/orders/update-shipment-line-items

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: api-2026-01
  version: 1.0.0
paths:
  /2026-01/shipment/{shipmentId}:updateLineItems:
    post:
      operationId: update-shipment-line-items
      summary: |
        Update Shipment Line Items
      description: >
        Updates the line items for a specific shipment. The request body must
        include the complete list of line items as returned by the GET
        /shipment/{shipmentId}:getLineItems endpoint — partial updates are not
        supported. Retrieve the current line items first, modify the desired
        fields, and submit the full payload.


        **Important:** The `is_manually_assigned_lot` field must be set to the
        same value for all line items in the request. When set to `true` on any
        item, ShipBob treats all lot assignments in the shipment as manually
        reviewed — ShipBob will not auto-assign or re-optimize lots for any
        item. When set to `false`, ShipBob manages lot selection automatically.
        Mixing `true` and `false` across items in the same request will result
        in a validation error.


        **Note on error handling:** This endpoint returns HTTP 200 for both
        successful and failed operations. Always check the `is_success` field in
        the response body to determine the outcome. When `is_success` is
        `false`, the `error` object contains the error code and message. HTTP
        400 is only returned when the request body itself is missing or empty.
      tags:
        - subpackage_orders
      parameters:
        - name: shipmentId
          in: path
          description: Unique identifier of the shipment
          required: true
          schema:
            $ref: >-
              #/components/schemas/Orders.Post.Api.V.Version.Shipment.ShipmentId.UpdateLineItems.ShipmentId.Integer
        - name: Authorization
          in: header
          description: Authentication using Personal Access Token (PAT) token
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Orders.ShipmentLineItemsApiResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Orders.ErrorResponse'
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Orders.UpdateLineItemsRequest'
servers:
  - url: https://sandbox-api.shipbob.com
    description: https://sandbox-api.shipbob.com
components:
  schemas:
    Orders.Post.Api.V.Version.Shipment.ShipmentId.UpdateLineItems.ShipmentId.Integer:
      type: integer
      title: >-
        Orders.Post.Api.V.Version.Shipment.ShipmentId.UpdateLineItems.ShipmentId.Integer
    Orders.ShipmentLineItemsViewModel:
      type: object
      properties:
        inventory_id:
          type: integer
          description: Unique identifier of the inventory item
        is_manually_assigned_lot:
          type: boolean
          description: >-
            Indicates whether the lot was manually assigned. When true, ShipBob
            treats all lot assignments in the shipment as manually reviewed.
            Must be the same value for all line items in the request.
        lot_date:
          type: string
          description: Expiration or manufacturing date of the lot
        lot_number:
          type: string
          description: Lot number of the inventory item
        quantity:
          type: integer
          description: Quantity of the inventory item in the shipment
      required:
        - inventory_id
        - quantity
      title: Orders.ShipmentLineItemsViewModel
    Orders.UpdateLineItemsRequest:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Orders.ShipmentLineItemsViewModel'
          description: >-
            Complete list of line items for the shipment. Must include all line
            items — partial updates are not supported
      required:
        - items
      title: Orders.UpdateLineItemsRequest
    Orders.ErrorCode:
      type: string
      enum:
        - INVALID_PARAMETER
        - VALIDATION_ERROR
        - DATABASE_UPDATE_ERROR
        - REPROCESSING_ERROR
        - DEALLOCATE_ERROR
        - NOT_FOUND
        - CONFLICT
      title: Orders.ErrorCode
    Orders.ErrorResponse:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/Orders.ErrorCode'
          description: Error code identifying the type of error
        message:
          type: string
          description: Human-readable description of the error
      title: Orders.ErrorResponse
    Orders.ShipmentLineItemResponse:
      type: object
      properties:
        action:
          type: string
          description: The action applied to this line item during the update
        inventory_id:
          type: integer
          description: Unique identifier of the inventory item
        new_value:
          type: string
          description: The new value of the field after the update
        previous_value:
          type: string
          description: The previous value of the field before the update
      title: Orders.ShipmentLineItemResponse
    Orders.ShipmentLineItemsApiResponse:
      type: object
      properties:
        error:
          oneOf:
            - $ref: '#/components/schemas/Orders.ErrorResponse'
            - type: 'null'
          description: Error details if the update was not successful
        id:
          type: integer
          format: int64
          description: Unique identifier of the shipment
        is_success:
          type: boolean
          description: Indicates whether the update was successful
        shipment_line_items:
          type: array
          items:
            $ref: '#/components/schemas/Orders.ShipmentLineItemResponse'
          description: List of line item changes applied to the shipment
      title: Orders.ShipmentLineItemsApiResponse
  securitySchemes:
    PAT:
      type: http
      scheme: bearer
      description: Authentication using Personal Access Token (PAT) token
    OAuth2:
      type: http
      scheme: bearer
      description: OAuth2 authentication using JWT tokens

```

## Examples



**Request**

```json
{
  "items": [
    {
      "inventory_id": 789012,
      "quantity": 5,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-06-01",
      "lot_number": "LOT-2024-001"
    },
    {
      "inventory_id": 789012,
      "quantity": 3,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-09-15",
      "lot_number": "LOT-2024-002"
    },
    {
      "inventory_id": 345678,
      "quantity": 1,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-11-01",
      "lot_number": "LOT-2024-003"
    }
  ]
}
```

**Response**

```json
{
  "error": {},
  "id": 476997333,
  "is_success": true,
  "shipment_line_items": [
    {
      "action": "ItemQtyUpdated",
      "inventory_id": 789012,
      "new_value": "10",
      "previous_value": "5"
    },
    {
      "action": "ItemRemoved",
      "inventory_id": 789012,
      "new_value": "0",
      "previous_value": "3"
    },
    {
      "action": "ItemAdded",
      "inventory_id": 789012,
      "new_value": "3",
      "previous_value": "0"
    }
  ]
}
```

**SDK Code**

```python default
import requests

url = "https://sandbox-api.shipbob.com/2026-01/shipment/1:updateLineItems"

payload = { "items": [
        {
            "inventory_id": 789012,
            "quantity": 5,
            "is_manually_assigned_lot": True,
            "lot_date": "2024-06-01",
            "lot_number": "LOT-2024-001"
        },
        {
            "inventory_id": 789012,
            "quantity": 3,
            "is_manually_assigned_lot": True,
            "lot_date": "2024-09-15",
            "lot_number": "LOT-2024-002"
        },
        {
            "inventory_id": 345678,
            "quantity": 1,
            "is_manually_assigned_lot": True,
            "lot_date": "2024-11-01",
            "lot_number": "LOT-2024-003"
        }
    ] }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript default
const url = 'https://sandbox-api.shipbob.com/2026-01/shipment/1:updateLineItems';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"items":[{"inventory_id":789012,"quantity":5,"is_manually_assigned_lot":true,"lot_date":"2024-06-01","lot_number":"LOT-2024-001"},{"inventory_id":789012,"quantity":3,"is_manually_assigned_lot":true,"lot_date":"2024-09-15","lot_number":"LOT-2024-002"},{"inventory_id":345678,"quantity":1,"is_manually_assigned_lot":true,"lot_date":"2024-11-01","lot_number":"LOT-2024-003"}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go default
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://sandbox-api.shipbob.com/2026-01/shipment/1:updateLineItems"

	payload := strings.NewReader("{\n  \"items\": [\n    {\n      \"inventory_id\": 789012,\n      \"quantity\": 5,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-06-01\",\n      \"lot_number\": \"LOT-2024-001\"\n    },\n    {\n      \"inventory_id\": 789012,\n      \"quantity\": 3,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-09-15\",\n      \"lot_number\": \"LOT-2024-002\"\n    },\n    {\n      \"inventory_id\": 345678,\n      \"quantity\": 1,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-11-01\",\n      \"lot_number\": \"LOT-2024-003\"\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby default
require 'uri'
require 'net/http'

url = URI("https://sandbox-api.shipbob.com/2026-01/shipment/1:updateLineItems")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"items\": [\n    {\n      \"inventory_id\": 789012,\n      \"quantity\": 5,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-06-01\",\n      \"lot_number\": \"LOT-2024-001\"\n    },\n    {\n      \"inventory_id\": 789012,\n      \"quantity\": 3,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-09-15\",\n      \"lot_number\": \"LOT-2024-002\"\n    },\n    {\n      \"inventory_id\": 345678,\n      \"quantity\": 1,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-11-01\",\n      \"lot_number\": \"LOT-2024-003\"\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java default
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://sandbox-api.shipbob.com/2026-01/shipment/1:updateLineItems")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"items\": [\n    {\n      \"inventory_id\": 789012,\n      \"quantity\": 5,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-06-01\",\n      \"lot_number\": \"LOT-2024-001\"\n    },\n    {\n      \"inventory_id\": 789012,\n      \"quantity\": 3,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-09-15\",\n      \"lot_number\": \"LOT-2024-002\"\n    },\n    {\n      \"inventory_id\": 345678,\n      \"quantity\": 1,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-11-01\",\n      \"lot_number\": \"LOT-2024-003\"\n    }\n  ]\n}")
  .asString();
```

```php default
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://sandbox-api.shipbob.com/2026-01/shipment/1:updateLineItems', [
  'body' => '{
  "items": [
    {
      "inventory_id": 789012,
      "quantity": 5,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-06-01",
      "lot_number": "LOT-2024-001"
    },
    {
      "inventory_id": 789012,
      "quantity": 3,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-09-15",
      "lot_number": "LOT-2024-002"
    },
    {
      "inventory_id": 345678,
      "quantity": 1,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-11-01",
      "lot_number": "LOT-2024-003"
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp default
using RestSharp;

var client = new RestClient("https://sandbox-api.shipbob.com/2026-01/shipment/1:updateLineItems");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"items\": [\n    {\n      \"inventory_id\": 789012,\n      \"quantity\": 5,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-06-01\",\n      \"lot_number\": \"LOT-2024-001\"\n    },\n    {\n      \"inventory_id\": 789012,\n      \"quantity\": 3,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-09-15\",\n      \"lot_number\": \"LOT-2024-002\"\n    },\n    {\n      \"inventory_id\": 345678,\n      \"quantity\": 1,\n      \"is_manually_assigned_lot\": true,\n      \"lot_date\": \"2024-11-01\",\n      \"lot_number\": \"LOT-2024-003\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift default
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["items": [
    [
      "inventory_id": 789012,
      "quantity": 5,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-06-01",
      "lot_number": "LOT-2024-001"
    ],
    [
      "inventory_id": 789012,
      "quantity": 3,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-09-15",
      "lot_number": "LOT-2024-002"
    ],
    [
      "inventory_id": 345678,
      "quantity": 1,
      "is_manually_assigned_lot": true,
      "lot_date": "2024-11-01",
      "lot_number": "LOT-2024-003"
    ]
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://sandbox-api.shipbob.com/2026-01/shipment/1:updateLineItems")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```