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

# Bulk Update Instructions


PUT https://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions
Content-Type: application/json

Sets the packing instructions and/or special SKU instructions on multiple shipments in a single request.

Each instruction field is optional, and omitting a field is different from sending an empty one:

* **Omit** the field, or send `null`, to leave that instruction unchanged.
* Send an **empty string** to clear that instruction.

At least one of the two must be provided with a **non-null** value — a request that omits both, or sends `null` for both, is rejected with `400 INVALID_PARAMETER`. `{"packing_instruction": null}` counts as providing nothing.

Each value is limited to 500 characters, measured **after** leading and trailing whitespace is removed. Whitespace padding around a 500-character instruction is therefore accepted.

`shipment_ids` is de-duplicated before the 250-shipment maximum is applied, and the response contains one result per unique id, in request order.

Instructions apply to B2B, SPS B2B, drop ship, kitting and inventory transfer shipments (including Amazon FBA). Direct-to-consumer shipments do not carry packing or SKU instructions.

Instructions can only be changed while a shipment is still editable. A shipment whose order type does not support instructions, that has been cancelled, cleanswept, shipped or completed, or that has already been assigned a tracking number, is reported as a per-shipment `BUSINESS_RULE_VIOLATION` rather than failing the whole request. A shipment that does not exist, or that belongs to another merchant, is reported as `NOT_FOUND`.

Submitting a value a shipment already has is a successful no-op: nothing is written and no audit entry is recorded.

Reference: https://developer.shipbob.com/api/orders/bulk-update-instructions

## Authentication

- `Authorization` header (bearer token, required) — Authentication using Personal Access Token (PAT) token
- `Authorization` header (bearer token, required) — OAuth2 authentication using JWT tokens

## Servers

- `https://api.shipbob.com` (https://api.shipbob.com, default)
- `https://sandbox-api.shipbob.com` (https://sandbox-api.shipbob.com)

## Request

### Body (application/json)

- `shipment_ids` (list of long, required) — Shipment IDs to update the instructions for. Duplicates are ignored, and the 250 maximum applies to the de-duplicated list.
- `packing_instruction` (string, optional, nullable) — Packing instructions for the shipments. Omit this field to leave the existing packing instructions unchanged; send an empty string to clear them. At least one of `packing_instruction` or `sku_instruction` must be provided with a non-null value. Leading and trailing whitespace is removed, and the 500-character limit applies to what remains.
- `sku_instruction` (string, optional, nullable) — Special SKU instructions for the shipments. Omit this field to leave the existing SKU instructions unchanged; send an empty string to clear them. At least one of `packing_instruction` or `sku_instruction` must be provided with a non-null value. Leading and trailing whitespace is removed, and the 500-character limit applies to what remains.

## Response

### 200

OK

- `summary` (object, required) — Summary of the bulk operation results
  - `failed` (integer, optional) — Number of shipments that failed to update
  - `successful` (integer, optional) — Number of shipments that were updated successfully
  - `total` (integer, optional) — Total number of shipments included in the bulk operation
- `results` (list of object, optional, nullable) — Per-shipment results of the bulk operation
  - `error` (object, optional, nullable) — Error details if the operation was not successful
    - `code` (enum, optional) — Error code identifying the type of error
      - Allowed values: `INVALID_PARAMETER`, `VALIDATION_ERROR`, `DATABASE_UPDATE_ERROR`, `REPROCESSING_ERROR`, `DEALLOCATE_ERROR`, `NOT_FOUND`, `CONFLICT`
    - `message` (string, optional, nullable) — Human-readable description of the error
  - `id` (long, optional) — Unique identifier of the shipment
  - `is_success` (boolean, optional) — Indicates whether the operation was successful for this shipment

## Examples

**Request**

```json
{
  "shipment_ids": [
    123456,
    789012
  ],
  "packing_instruction": "Fragile - double box",
  "sku_instruction": "Label each unit"
}
```

**Response**

```json
{
  "summary": {
    "failed": 0,
    "successful": 2,
    "total": 2
  },
  "results": [
    {
      "id": 123456,
      "is_success": true
    }
  ]
}
```

**SDK Code**

```python default
import requests

url = "https://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions"

payload = {
    "shipment_ids": [123456, 789012],
    "packing_instruction": "Fragile - double box",
    "sku_instruction": "Label each unit"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript default
const url = 'https://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions';
const options = {
  method: 'PUT',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"shipment_ids":[123456,789012],"packing_instruction":"Fragile - double box","sku_instruction":"Label each unit"}'
};

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://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions"

	payload := strings.NewReader("{\n  \"shipment_ids\": [\n    123456,\n    789012\n  ],\n  \"packing_instruction\": \"Fragile - double box\",\n  \"sku_instruction\": \"Label each unit\"\n}")

	req, _ := http.NewRequest("PUT", 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://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions")

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

request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"shipment_ids\": [\n    123456,\n    789012\n  ],\n  \"packing_instruction\": \"Fragile - double box\",\n  \"sku_instruction\": \"Label each unit\"\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.put("https://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"shipment_ids\": [\n    123456,\n    789012\n  ],\n  \"packing_instruction\": \"Fragile - double box\",\n  \"sku_instruction\": \"Label each unit\"\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions', [
  'body' => '{
  "shipment_ids": [
    123456,
    789012
  ],
  "packing_instruction": "Fragile - double box",
  "sku_instruction": "Label each unit"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp default
using RestSharp;

var client = new RestClient("https://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"shipment_ids\": [\n    123456,\n    789012\n  ],\n  \"packing_instruction\": \"Fragile - double box\",\n  \"sku_instruction\": \"Label each unit\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift default
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "shipment_ids": [123456, 789012],
  "packing_instruction": "Fragile - double box",
  "sku_instruction": "Label each unit"
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.shipbob.com/2026-07/shipment:bulkUpdateInstructions")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
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()
```