Add or remove stock for products and variants in the authenticated account. Send updates with warehouse_id, product_id, action (add/remove), origin and a positive quantity. All operations must use the same warehouse. For a variant, also send product_variant_id from the product's variants response; keep product_id as the owning product ID. Omitted or null product_variant_id uses the existing product-level operation. The response includes product_variant_id for each returned stock record. This operation is not idempotent; reconcile actual stock after an uncertain result before retrying. For origin purchase, supply both unit_cost (unit cost with taxes) and unit_cost_base (unit cost without taxes). Both must be finite and non-negative; zero is explicit, omission/null returns 400 for purchases. For other origins the pair is optional, but supplying one requires both. Products applies the existing last-purchase and weighted-average rules to the product or variant; cost is per unit, not the line total.
Header Parameters
Your API Key for authentication
Request Body
application/json
Stock movements. Purchase costs are per unit: unit_cost with taxes and unit_cost_base without taxes, both required for origin purchase. Optional product_variant_id identifies a variant of product_id in warehouse_id. Example: {"updates":[{"warehouse_id":"WAREHOUSE_ID","product_id":"PRODUCT_ID","product_variant_id":"VARIANT_ID","action":"add","origin":"adjustment","quantity":2}]}
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/products/stock" \ -H "X-Api-Key: string" \ -H "Content-Type: application/json" \ -d '{}'[ { "warehouse_id": "string", "product_id": "string", "product_variant_id": "string", "stock": 0, "reserved": 0 }]Search products POST
Search products in the account associated with your API key. Supports text search, inventory and price filters, variant attributes, catalogs, collections, sorting and facet counts. Requires `products:read`. The request and response use **camelCase**. ### Parameters All parameters are optional. Send `{}` to list active products across the account's warehouses. Do not send `accountId`: the account comes from the authenticated key. | Parameter | Meaning and default | | --- | --- | | `query` | Text search; default `"*"` matches all. Searches name, SKU, description, indexed content and locations. This is not an exact barcode lookup. | | `warehouseId` | Restrict to one warehouse. Omit to search all warehouses in the account. | | `productCategoryName` | Exact category name, for example `"Clothing"`. | | `measurement` | Exact measurement value. | | `productId` | Restrict to a product ID. Without an explicit status or catalog, this lookup does not apply the default active-only filter. | | `productStatus` | Normally defaults to `"Active"`. Indexed product statuses are `"Active"` and `"Inactive"` (case-sensitive). Catalog and collection searches only accept active products. | | `salesCatalogId` | Active sales catalog belonging to this account; independent of warehouse. | | `collectionId` | Product collection belonging to this account. Can combine with a catalog. | | `filter` | Additional OData conditions; examples below. Field names inside this string are **PascalCase** and case-sensitive. | | `orderBy` | Sort field and direction, for example `"ProductName asc"`, `"Available desc"`, `"Price1 asc"` or `"UpdatedAt desc"`. Omit for search relevance. | | `facets` | Fields whose matching value counts you want, for example `["ProductCategoryName,count:50", "VariantAttributeValues"]`. Counts do not add filters automatically. | | `pageNumber` | Page starting at 1; default 1. | | `pageSize` | Results per page, 1–100; default 20. | ### Filters Use numeric comparisons `eq`, `ne`, `gt`, `ge`, `lt`, `le`; combine conditions with `and`, `or`, `not` and parentheses. Strings use single quotes; escape a quote by doubling it, for example `'Men''s clothing'`. Use the dedicated parameters for account, warehouse, status and product restrictions. | Need | Example `filter` | | --- | --- | | Available inventory | `Available gt 0` | | Out of stock | `Available le 0` | | Minimum physical stock | `Stock ge 10` | | Price list range | `Price1 ge 5000 and Price1 le 50000` | | Base price range | `PriceBase ge 5000 and PriceBase le 50000` | | Category ID | `ProductCategoryId eq 'category-id'` | | Products with variants | `HasVariants eq true` | | Missing images | `HasImage eq false` | | Raw materials | `IsRawMaterial eq true` | | Serial or optional tracking | `IncludesSerials eq true and IncludesOptionals eq false` | | Variant attribute | `VariantAttributeValues/any(v: v eq 'Color:Rojo')` | | Feature | `FeatureKeys/any(f: f eq 'Material:Algodón')` | | Custom field | `CustomFieldKeys/any(f: f eq 'proveedor:sony')` | | With discounts | `DiscountKeys/any()` | | Changed since a date | `UpdatedAt ge 2026-10-01T00:00:00Z` | Collection filters match products. A variant-attribute filter selects matching products; it does not trim the returned variants to that attribute. Catalog and collection memberships do restrict the returned variants. Stock and price filters apply to the indexed document, not to an individual matching variant. ### Examples Search available products with a price range and category counts: ```json { "query": "shirt", "warehouseId": "warehouse-id", "filter": "Available gt 0 and Price1 ge 5000 and Price1 le 50000", "orderBy": "ProductName asc", "facets": ["ProductCategoryName,count:50", "VariantAttributeValues"], "pageNumber": 1, "pageSize": 20 } ``` Discover variant values and features: ```json { "query": "*", "filter": "HasVariants eq true", "facets": ["VariantAttributeValues,count:100", "FeatureKeys,count:50"] } ``` Restrict a catalog to a collection and warehouse: ```json { "salesCatalogId": "catalog-id", "collectionId": "collection-id", "warehouseId": "warehouse-id", "orderBy": "ProductName asc" } ``` ### Facets and catalogs Useful facets include `ProductCategoryName`, `WarehouseId`, `Measurement`, `VariantAttributeNames`, `VariantAttributeValues`, `FeatureKeys`, `CustomFieldKeys` and `DiscountKeys`. Request `count:N` to control the number of returned values. Apply a selection by issuing another request with a `filter`, such as `ProductCategoryName eq 'Clothing'`. With `salesCatalogId` or `collectionId`, allowed facets are `ProductCategoryName`, `WarehouseId`, `Measurement`, `VariantAttributeValues`, `FeatureKeys`, `CustomFieldKeys` and `References`. Allowed sort fields are `ProductName`, `PriceBase`, `Price1`–`Price10`, `TotalSales`, `Available`, `Stock` and `Weight`. An unavailable catalog or collection returns an empty page. Facet counts and filtering use the indexed document's full variant aggregates, even when membership limits returned variants. ### Reading results The response contains `results`, `totalCount`, `pageNumber`, `pageSize`, `totalPages` and `facets`. Each result is a **product/warehouse document**. Without `warehouseId`, the same product can appear in multiple warehouses. Use `productId` for product operations; `id` identifies the search document. Results include `stock`, `reserved`, `available`, `prices` (`base`, `price1`–`price10`), `variants`, taxes and discounts. Variants include `productVariantId`, their stock, attributes and `variantPrices`. Facet keys preserve Search field names such as `ProductCategoryName`. ### Synchronization New products and inventory changes are indexed asynchronously and may take a short interval to appear. There is no guaranteed one-second maximum. An empty result does not prove a product was not created; use GET by product ID to check a recent write. Full index rebuilds can temporarily return partial or empty results.
Change shipment status PUT
Change the status of a shipment in the authenticated account. Shipment, parent order and target status must belong to this account; missing or foreign resources return 404. Updates the current status of a shipment to the specified next status.