> This page is for version v1.0.
> For other versions, use one of these documentation indexes:
> - 2026-07 (default): https://developer-stage.shipbob.dev/2026-07/llms.txt
> - 2026-01: https://developer-stage.shipbob.dev/2026-01/llms.txt
> - 2025-07: https://developer-stage.shipbob.dev/2025-07/llms.txt
> - v2.0: https://developer-stage.shipbob.dev/v2.0/llms.txt
> - v1.0: https://developer-stage.shipbob.dev/v1.0/llms.txt
> - Experimental: https://developer-stage.shipbob.dev/experimental/llms.txt

> 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.

# Get multiple products


GET https://sandbox-api.shipbob.com/1.0/product

Reference: https://developer-stage.shipbob.dev/v1.0/api/products/get-multiple-products

## Authentication

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

## Request

### Query parameters

- `ReferenceIds` (list of string, optional) — Comma separated list of reference ids to filter by
- `Page` (integer, optional) — Page of products to get - Valid Range is 0 to integer max with a default of 1
- `Limit` (integer, optional) — Amount of products per page to request - Valid Range is 1 to 250 with a default of 50
- `IDs` (list of integer, optional) — Comma separated list of product ids to filter by
- `Search` (string, optional) — Search is available for 2 fields of the inventory record related to the product: Inventory ID and Name - 1. Expected behavior for search by Inventory ID is exact match 2. Expected behavior for search by Inventory Name is partial match, i.e. does not have to be start of word, but must be consecutive characters. This is not case sensitive.
- `ActiveStatus` (enum, optional) — Status filter for products: - Any: Include both active and inactive - Active: Filter products that are Active - Inactive: Filter products that are Inactive",
  - Allowed values: `Any`, `Active`, `Inactive`
- `BundleStatus` (enum, optional) — Bundle filter for products: - Any: Don't filter and consider products that are bundles or not bundles - Bundle: Filter by products that are bundles - NotBundle: Filter by products that are not bundles"
  - Allowed values: `Any`, `Bundle`, `NotBundle`

### Headers

- `shipbob_channel_id` (integer, optional) — Channel Id for Operation

## Response

### 200

Success

- `list of Products.ProductViewModel`

## Errors

### 400 Bad Request Error

Bad Request

- `map from string to list of string`

### 401 Unauthorized Error

No access right at this time

- `any`

### 403 Forbidden Error

No access

- `any`

## Types

### Products.ProductViewModel

- `barcode` (string, optional, nullable) — Barcode for the product
- `bundle_root_information` (Products.BundleRootInformationViewModel, optional)
- `channel` (Products.ChannelViewModel, optional) — Information about a store channel
- `created_date` (datetime, optional) — Date the product was created
- `fulfillable_inventory_items` (list of Products.InventoryItemViewModel, optional, nullable) — The inventory that this product will resolve to when packing a shipment
- `fulfillable_quantity_by_fulfillment_center` (list of Products.FulfillmentCenterQuantityViewModel, optional, nullable) — Fulfillable quantity of this product broken down by fulfillment center location
- `gtin` (string, optional, nullable) — Global Trade Item Number - unique and internationally recognized identifier assigned to item by company GS1.
- `id` (integer, optional) — Unique identifier of the product
- `name` (string, optional, nullable) — The name of the product
- `reference_id` (string, optional, nullable) — Unique reference identifier of the product
- `sku` (string, optional, nullable) — Stock keeping unit for the product
- `total_committed_quantity` (integer, optional) — Total committed quantity of this product
- `total_fulfillable_quantity` (integer, optional) — Total fulfillable quantity of this product
- `total_onhand_quantity` (integer, optional) — Total on hand quantity of this product
- `unit_price` (double, optional, nullable) — The price of one unit
- `upc` (string, optional, nullable) — Universal Product Code - Unique external identifier

### Products.BundleRootInformationViewModel

- `id` (integer, optional) — Id of the bundle root product
- `name` (string, optional, nullable) — Name of the bundle root product

### Products.ChannelViewModel

Information about a store channel

- `id` (integer, optional) — Unique id of the store channel
- `name` (string, optional, nullable) — Name of the store channel

### Products.InventoryItemViewModel

The inventory that store products can resolve to when packing a shipment

- `id` (integer, optional) — Unique id of the inventory item
- `name` (string, optional, nullable) — Name of the inventory item
- `quantity` (integer, optional) — Quantity of the inventory item included in a store product

### Products.FulfillmentCenterQuantityViewModel

Break down of quantities by fulfillment center

- `committed_quantity` (integer, optional) — Amount of committed quantity at this fulfillment center
- `fulfillable_quantity` (integer, optional) — Amount of fulfillable quantity at this fulfillment center
- `id` (integer, optional) — Unique id of the fulfillment center
- `name` (string, optional, nullable) — Name of the fulfillment center
- `onhand_quantity` (integer, optional) — Amount of onhand quantity at this fulfillment center

## Examples

**Response**

```json
[
  {
    "barcode": "123456789012",
    "bundle_root_information": {
      "id": 0,
      "name": "string"
    },
    "channel": {
      "id": 0,
      "name": "House of Slippers"
    },
    "created_date": "2019-08-24T14:15:22+00:00",
    "fulfillable_inventory_items": [
      {
        "id": 0,
        "name": "Medium Blue T-Shirt",
        "quantity": 0
      }
    ],
    "fulfillable_quantity_by_fulfillment_center": [
      {
        "committed_quantity": 0,
        "fulfillable_quantity": 0,
        "id": 0,
        "name": "Cicero",
        "onhand_quantity": 0
      }
    ],
    "gtin": "012345678905",
    "id": 0,
    "name": "Medium Blue T-Shirt",
    "reference_id": "TShirtBlueM",
    "sku": "TShirtBlueM",
    "total_committed_quantity": 0,
    "total_fulfillable_quantity": 0,
    "total_onhand_quantity": 0,
    "unit_price": 20.32,
    "upc": "012345678912"
  }
]
```

**SDK Code**

```python default
import requests

url = "https://sandbox-api.shipbob.com/1.0/product"

querystring = {"ReferenceIds":"[\"string\"]","Page":"2147483647","Limit":"1","IDs":"[0]","Search":"string","ActiveStatus":"Any","BundleStatus":"Any"}

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers, params=querystring)

print(response.json())
```

```javascript default
const url = 'https://sandbox-api.shipbob.com/1.0/product?ReferenceIds=%5B%22string%22%5D&Page=2147483647&Limit=1&IDs=%5B0%5D&Search=string&ActiveStatus=Any&BundleStatus=Any';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

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"
	"net/http"
	"io"
)

func main() {

	url := "https://sandbox-api.shipbob.com/1.0/product?ReferenceIds=%5B%22string%22%5D&Page=2147483647&Limit=1&IDs=%5B0%5D&Search=string&ActiveStatus=Any&BundleStatus=Any"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	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/1.0/product?ReferenceIds=%5B%22string%22%5D&Page=2147483647&Limit=1&IDs=%5B0%5D&Search=string&ActiveStatus=Any&BundleStatus=Any")

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

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

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.get("https://sandbox-api.shipbob.com/1.0/product?ReferenceIds=%5B%22string%22%5D&Page=2147483647&Limit=1&IDs=%5B0%5D&Search=string&ActiveStatus=Any&BundleStatus=Any")
  .header("Authorization", "Bearer <token>")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://sandbox-api.shipbob.com/1.0/product?ReferenceIds=%5B%22string%22%5D&Page=2147483647&Limit=1&IDs=%5B0%5D&Search=string&ActiveStatus=Any&BundleStatus=Any', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp default
using RestSharp;

var client = new RestClient("https://sandbox-api.shipbob.com/1.0/product?ReferenceIds=%5B%22string%22%5D&Page=2147483647&Limit=1&IDs=%5B0%5D&Search=string&ActiveStatus=Any&BundleStatus=Any");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift default
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://sandbox-api.shipbob.com/1.0/product?ReferenceIds=%5B%22string%22%5D&Page=2147483647&Limit=1&IDs=%5B0%5D&Search=string&ActiveStatus=Any&BundleStatus=Any")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

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()
```