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

# Find records by business identifiers

> Find products, shipments, invoices, suppliers, and related records by the identifiers you already have

Set your [API key and brand](/authentication). Use exact lookups for identifiers
from your ERP or PIM, then use the returned UUID for detail and relationship reads.
All paths below start at `/api/public/v1/brands/{brand}`.

| You know | Request |
| - | - |
| Parent Product code | `/products?code=TEE-001` |
| Part of a product name or code | `/products?q=cotton` |
| Product Option name and parent | `/product-options?productId={id}&name=Ocean` |
| SKU code or UPC | `/skus?code=TEE-001-M` or `/skus?upc=012345678901` |
| Purchase-order number | `/orders?orderNumber=PO-2026-0042` |
| Your external order reference | `/orders?externalOrderCode=ERP-42` |
| Quotes for a product and supplier | `/quotes?productId={id}&supplierId={id}` |
| Quote number | `/quotes?quoteNumber=RFQ-2026-0081` |
| Shipment code | `/shipments?shipmentCode=SHP-2026-0042` |
| Tracking number and carrier | `/shipments?trackingNumber=JD0146000123456789&carrierSlug=dhl` |
| Container number | `/shipments?containerNumber=MSCU1234567` |
| Forwarder's reference | `/shipments?source=manual&externalShipmentId=EXT-42` |
| Booking reference | `/bookings?externalBookingReference=BOOK-42&source=manual` |
| Packing-list reference | `/packing-lists?reference=PL-42` |
| Goods-receipt number | `/goods-receipts?receiptNumber=GR-42` |
| Invoice number and issuer | `/invoices?invoiceNumber=INV-42&issuerPartnerId={id}` |
| Payment reference | `/payment-receipts?paymentReference=BANK-42` |
| Supplier slug | `/suppliers?slug=textile-co` |
| Contact email | `/contacts?email=orders%40textile.example` |
| Sample code | `/samples?code=SAMPLE-42` |
| Material code | `/materials?code=FAB-001` |
| Color code | `/colors?code=NAVY` |
| Port code | `/locations?unLocode=USLAX` |
| Document filename | `/documents?fileName=invoice-42.pdf` |

Exact filters are case-sensitive. Product `q` search is case-insensitive and
matches a literal substring, including `%` and `_` as ordinary characters.
Combine filters with AND; for example, `code=TEE-001&status=active`.
Product Option names and external references can match several records, so every
lookup returns the standard page envelope. Zero matches is an empty page.
Unknown or invalid parameters return `400` instead of silently broadening a read.
See [filters by entity](/lookup-filters) for the complete collection selector list.

```bash theme={null}
curl --fail-with-body --get \
  -H "Authorization: Bearer $AMBER_API_KEY" \
  --data-urlencode "code=TEE-001" \
  "https://app.amber.ai/api/public/v1/brands/$AMBER_BRAND/products"
```

Save [`amber-client.mjs`](/pagination#reusable-nodejs-client), then run this with
Node.js 22 or later and `PRODUCT_CODE` set to a known code:

```javascript find-product.mjs theme={null}
import { apiUrl, records, productGraph } from "./amber-client.mjs";

const code = process.env.PRODUCT_CODE;
if (!code) throw new Error("Set PRODUCT_CODE");
for await (const product of records(apiUrl("products", { code }))) {
  const packet = await productGraph(product.id, "versions,boms,bomComponents,measurementTables,productOptions,skus");
  console.log(JSON.stringify(packet));
}
```

Keep IDs as your local join keys. Product codes and names can change; the UUID
identifies the same record across those edits. When paginating, preserve the
brand, resource and filters. Reusing a cursor for a different lookup returns `400`.

## Find one shipment and read its contents

Use `shipmentCode` when you have Amber's code. For carrier events, combine
`trackingNumber` and `carrierSlug`; for imported shipments, combine
`externalShipmentId` and `source`. A `containerNumber` lookup matches membership
in the shipment's `containerNumbers` array.

```bash theme={null}
curl --fail-with-body --get \
  -H "Authorization: Bearer $AMBER_API_KEY" \
  --data-urlencode "shipmentCode=SHP-2026-0042" \
  --data-urlencode "limit=2" \
  "https://app.amber.ai/api/public/v1/brands/$AMBER_BRAND/shipments"
```

If you expect exactly one match, check `totalItems` before choosing it. Do not
silently take `items[0]` when several records share a reference. This script
fails on ambiguity and fetches only the selected shipment's lines and cartons:

```javascript find-shipment.mjs theme={null}
import { apiUrl, readJson, records } from "./amber-client.mjs";

const shipmentCode = process.env.SHIPMENT_CODE;
if (!shipmentCode) throw new Error("Set SHIPMENT_CODE");
const page = await readJson(apiUrl("shipments", { shipmentCode, limit: 2 }));
if (page.totalItems !== 1 || page.items.length !== 1) {
  throw new Error(`Expected one shipment; found ${page.totalItems}`);
}
const shipment = page.items[0];
const items = [];
const cartons = [];
for await (const item of records(apiUrl("shipment-items", { shipmentId: shipment.id }))) {
  items.push(item);
}
for await (const carton of records(apiUrl("shipment-cartons", { shipmentId: shipment.id }))) {
  cartons.push(carton);
}
console.log(JSON.stringify({ shipment, items, cartons }, null, 2));
```

## Disambiguate repeated references

Identifiers often belong to a parent or an issuing organization. Use both parts
when you know them:

| Record | Selectors to combine |
| - | - |
| Supplier invoice | `invoiceNumber` + `issuerPartnerId`; `supplierId` identifies the order supplier and can differ from the issuer |
| Carton | `packingListId` + `cartonNumber` |
| Product version | `productId` + `versionNumber` |
| Quote revision | `rfqId` + `round`; `rfqId` is the parent Quote ID returned by `/quotes` |
| Quote price band | `quoteItemId` + `bandNumber` |
| Production run | `orderId` + `runNumber` |
| Payment obligation | `sourceKind` + `sourceKey`, with `scopeKey` if needed |
| Dimension curve cell | `curveId` + `rowIndex` + `colIndex` |

These combinations narrow a read; they do not promise that every source has a
unique business reference. Use the matching record's stable ID for future reads.

## Look up reference values before joining

Resolve `/colors?code=NAVY` or `/materials?code=FAB-001` once, then use the
returned IDs in relationship filters. For example, `/material-variants` accepts
`componentId`, `colorId`, and `supplierMaterialVariantCode`. A child without its
own business code is still addressable by its parent and related IDs: use
`/shipment-carton-items?shipmentCartonId={id}&skuId={id}` to read one carton's
matching SKU rows.

Boolean selectors use `true` or `false`. Integer selectors use ordinary whole
numbers without leading zeros, such as `versionNumber=0` or `rowIndex=0`.
Always URL-encode values, especially email addresses, spaces, `+`, `&`, and `#`.
