Pular para o conteúdo

Products

Este conteúdo não está disponível em sua língua ainda.

Products (also called parts or inventory items) are the line-item catalog entries in BenchKey. Each product has a name, optional SKU, pricing, and stock settings. Inventory quantities are tracked separately per location, see Inventory for adjusting stock. Deleting a product archives it (sets it inactive) rather than permanently removing it.

{
"object": "product",
"id": 42,
"name": "iPhone 14 Screen Assembly",
"sku": "SCR-IP14-OEM",
"description": "OEM-grade OLED screen assembly for iPhone 14",
"condition": "new",
"unit": "each",
"category_id": 3,
"category_name": "Screens",
"qty_on_hand": 5,
"min_stock": 2,
"low_stock": false,
"serial_tracked": false,
"active": true,
"sell_price": { "amount_cents": 8999, "amount": "89.99", "currency": "USD" },
"last_cost": { "amount_cents": 4500, "amount": "45.00", "currency": "USD" },
"avg_cost": { "amount_cents": 4750, "amount": "47.50", "currency": "USD" },
"default_vendor_id": 7,
"vendor_sku": "AAPL-SCR-14",
"notes": null,
"created_at": "2025-09-01T10:00:00.000Z",
"updated_at": "2025-11-15T14:30:00.000Z"
}
FieldTypeDescription
idintegerUnique product ID
namestringDisplay name
skustring|nullYour internal SKU, or null if not set
descriptionstring|nullOptional long description
conditionstring"new", "used", "refurbished", etc.
unitstringUnit of measure (e.g. "each", "pair")
category_idinteger|nullCategory ID, or null
category_namestring|nullCategory display name, or null
qty_on_handintegerTotal units on hand across all locations
min_stockintegerReorder threshold; 0 means no threshold set
low_stockbooleantrue when min_stock > 0 and qty_on_hand ≤ min_stock
serial_trackedbooleanWhether serial numbers are required at point of sale
activebooleanfalse if the product has been archived
sell_priceMoney|nullRetail sell price (amount_cents, amount, currency)
last_costMoney|nullLast purchase cost (amount_cents, amount, currency)
avg_costMoney|nullMoving-average cost, read-only (amount_cents, amount, currency)
default_vendor_idinteger|nullPreferred vendor ID for purchase orders
vendor_skustring|nullVendor’s part number
notesstring|nullInternal notes
created_atstringISO-8601 creation timestamp
updated_atstringISO-8601 last-updated timestamp

GET /api/v1/products

Returns a cursor-paginated list of products ordered by most recently created first. Active products are returned by default; pass active=all to include archived items.

Scope required: products.read

ParameterTypeDescription
qstringPartial-match search across name and sku, max 255 chars
skustringExact SKU match, max 255 chars
category_idintegerFilter by category (positive integer ≤ 2,147,483,647; out-of-range values return 400 invalid_query)
low_stockbooleanPass true to return only items at or below min_stock
activestringPass "all" to include inactive (archived) products
limitintegerPage size, 1–100 (default: 20)
cursorstringOpaque cursor from a previous response’s next_cursor
Terminal window
curl "https://app.benchkey.com/api/v1/products?q=iphone&limit=20" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch(
"https://app.benchkey.com/api/v1/products?q=iphone&limit=20",
{ headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" } }
);
const { data, has_more, next_cursor } = await res.json();
{
"object": "list",
"data": [
{
"object": "product",
"id": 42,
"name": "iPhone 14 Screen Assembly",
"sku": "SCR-IP14-OEM",
"description": null,
"condition": "new",
"unit": "each",
"category_id": 3,
"category_name": "Screens",
"qty_on_hand": 5,
"min_stock": 2,
"low_stock": false,
"serial_tracked": false,
"active": true,
"sell_price": { "amount_cents": 8999, "amount": "89.99", "currency": "USD" },
"last_cost": { "amount_cents": 4500, "amount": "45.00", "currency": "USD" },
"avg_cost": { "amount_cents": 4750, "amount": "47.50", "currency": "USD" },
"default_vendor_id": 7,
"vendor_sku": null,
"notes": null,
"created_at": "2025-09-01T10:00:00.000Z",
"updated_at": "2025-11-15T14:30:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}

See Pagination for how to page through results.


GET /api/v1/products/:id

Returns a single product by ID.

Scope required: products.read

Terminal window
curl "https://app.benchkey.com/api/v1/products/42" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch(
"https://app.benchkey.com/api/v1/products/42",
{ headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" } }
);
const product = await res.json();

Returns a single product object. Returns 404 if no product with that ID exists or if the product is inactive, archived products are hidden by default, matching the list behavior. Pass ?active=all to retrieve an inactive product by ID.


POST /api/v1/products

Creates a new product in your catalog. Prices are supplied in integer cents (sell_price_cents, last_cost_cents).

Scope required: products.write

FieldRequiredDescription
nameyesProduct display name
skunoInternal SKU
descriptionnoLong description
conditionno"new", "used", "refurbished", etc.
unitnoUnit of measure (default: "each")
category_idnoCategory ID to assign
min_stocknoReorder threshold (non-negative integer)
sell_price_centsnoRetail sell price in integer cents (e.g. 8999 = $89.99)
last_cost_centsnoLast purchase cost in integer cents
default_vendor_idnoPreferred vendor ID
serial_trackednotrue to require serial numbers at sale
notesnoInternal notes
Terminal window
curl -X POST "https://app.benchkey.com/api/v1/products" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" \
-H "Content-Type: application/json" \
-d '{
"name": "iPhone 14 Battery",
"sku": "BAT-IP14",
"condition": "new",
"category_id": 5,
"sell_price_cents": 3999,
"last_cost_cents": 1200,
"min_stock": 3
}'
const res = await fetch("https://app.benchkey.com/api/v1/products", {
method: "POST",
headers: {
Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "iPhone 14 Battery",
sku: "BAT-IP14",
condition: "new",
category_id: 5,
sell_price_cents: 3999,
last_cost_cents: 1200,
min_stock: 3,
}),
});
const product = await res.json(); // 201 Created

Returns the created product object with HTTP 201 Created.


PATCH /api/v1/products/:id

Updates one or more fields on a product. Only fields you include in the request body are changed. To update sell price or cost, supply sell_price_cents or last_cost_cents in integer cents.

Quantity adjustments are not made here, use POST /inventory/:product_id/adjust instead.

Scope required: products.write

All fields are optional. Supply only the fields you want to change.

FieldDescription
nameNew display name
skuNew SKU
descriptionNew description
conditionNew condition string
unitNew unit of measure
category_idNew category ID (null to unset)
min_stockNew reorder threshold
sell_price_centsNew sell price in integer cents
last_cost_centsNew last cost in integer cents
default_vendor_idNew preferred vendor ID
serial_trackedToggle serial-number tracking
notesNew notes
Terminal window
curl -X PATCH "https://app.benchkey.com/api/v1/products/42" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" \
-H "Content-Type: application/json" \
-d '{
"sell_price_cents": 7999,
"min_stock": 5
}'
const res = await fetch("https://app.benchkey.com/api/v1/products/42", {
method: "PATCH",
headers: {
Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa",
"Content-Type": "application/json",
},
body: JSON.stringify({ sell_price_cents: 7999, min_stock: 5 }),
});
const product = await res.json();

Returns the updated product object.


DELETE /api/v1/products/:id

Archives a product by setting it to inactive. Archived products are hidden from list results by default (pass active=all to include them). Hard deletion is not supported, BenchKey preserves historical line-item data on past tickets and invoices.

Scope required: products.write

Terminal window
curl -X DELETE "https://app.benchkey.com/api/v1/products/42" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch("https://app.benchkey.com/api/v1/products/42", {
method: "DELETE",
headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" },
});
const result = await res.json();
// { "object": "product", "id": 42, "archived": true }
{
"object": "product",
"id": 42,
"archived": true
}

To restore an archived product, use the BenchKey app, the public API does not expose an unarchive endpoint.


HTTP statusCodeMeaning
400invalid_queryA list filter parameter was supplied as an array or object instead of a single scalar value
400invalid_cursorcursor is malformed
400invalid_idPath :id is not a valid integer
400missing_fieldRequired field name was not provided
400invalid_fieldsell_price_cents, last_cost_cents, or min_stock is not a non-negative integer; q or sku exceeds 255 characters; category_id does not exist; default_vendor_id does not exist or belongs to an inactive vendor
400nothing_to_updatePATCH body contained no updatable fields
404not_foundNo product with that ID exists
422create_failedInternal error prevented product creation
422update_failedInternal error prevented product update
422archive_failedInternal error prevented archiving
403insufficient_scopeAPI key lacks products.read or products.write

See Errors for the full error envelope format.

Status do sistema