openapi: 3.2.0 info: title: Happy Buyers External Inventory Health API description: 'External API for Happy Buyers organization metadata and inventory data. Requests are authenticated with an API key in the hca-api-key header. Results are scoped to the organization attached to that key. List endpoints use limit/offset pagination and return totalCount plus hasMore. ' version: v1 servers: - url: https://api.happycabbage.ai description: External API security: - ApiKeyAuth: [] tags: - name: Inventory Health description: Inventory health data paths: /external/v1/inventory-health/stores: get: tags: - Inventory Health summary: List store inventory health description: Returns store-level inventory health metrics for the API key organization. Results are always separated by store. Requires inventory:read. operationId: getStoreInventoryHealths parameters: - name: offset in: query description: Zero-based result offset for pagination. required: false schema: minimum: 0 type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of inventory health rows to return. Maximum is 500. required: false schema: maximum: 500 minimum: 0 type: integer format: int32 default: 100 example: 100 - name: storeIds in: query description: Store UUID filters. Pass repeated query parameters, for example storeIds=id1&storeIds=id2. required: false schema: type: array items: type: string format: uuid example: 11111111-1111-1111-1111-111111111111 - name: brandIds in: query description: POS brand ID filters. Pass repeated query parameters, for example brandIds=1&brandIds=2. required: false schema: type: array items: type: integer format: int32 example: 99 - name: categoryIds in: query description: POS category ID filters. Pass repeated query parameters, for example categoryIds=1&categoryIds=2. required: false schema: type: array items: type: integer format: int32 example: 42 - name: search in: query description: Search text matched against the fields returned by the route. required: false schema: type: string - name: includePercentShares in: query description: Whether to include percent-share fields. required: false schema: type: boolean example: false - name: sortTarget in: query description: Field to sort by. required: false schema: type: string enum: - UNITS_PER_DAY - UPDATED_AT - PERCENT_SHARE_OF_PROFIT - PERCENT_SHARE_OF_AGED_INVENTORY_COST - PERCENT_SHARE_OF_DOLLARS_SOLD - PERCENT_SHARE_OF_UNITS_SOLD example: UNITS_PER_DAY - name: sortDirection in: query description: Sort direction. Prefer ASC or DESC; lowercase values are deprecated aliases. required: false schema: type: string enum: - asc - desc - ASC - DESC - ASC_NULLS_FIRST - ASC_NULLS_LAST - DESC_NULLS_FIRST - DESC_NULLS_LAST example: DESC responses: '403': description: API key does not include inventory:read '401': description: Missing, malformed, or invalid API key '200': description: Paged store inventory health results content: application/json: schema: $ref: '#/components/schemas/LimitOffsetResponseStoreResponse' '400': description: Invalid query parameter /external/v1/inventory-health/stores/history: get: tags: - Inventory Health summary: List store inventory health history description: Returns historical store-level inventory health metrics for the API key organization. Results are always separated by store. Requires inventory:read. operationId: getStoreInventoryHealthHistories parameters: - name: offset in: query description: Zero-based result offset for pagination. required: false schema: minimum: 0 type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of inventory health rows to return. Maximum is 500. required: false schema: maximum: 500 minimum: 0 type: integer format: int32 default: 100 example: 100 - name: storeIds in: query description: Store UUID filters. Pass repeated query parameters, for example storeIds=id1&storeIds=id2. required: false schema: type: array items: type: string format: uuid example: 11111111-1111-1111-1111-111111111111 - name: search in: query description: Search text matched against the fields returned by the route. required: false schema: type: string - name: sortTarget in: query description: Field to sort by. required: false schema: type: string enum: - START_DATE - UNITS_PER_DAY - UPDATED_AT example: START_DATE - name: sortDirection in: query description: Sort direction. Prefer ASC or DESC; lowercase values are deprecated aliases. required: false schema: type: string enum: - asc - desc - ASC - DESC - ASC_NULLS_FIRST - ASC_NULLS_LAST - DESC_NULLS_FIRST - DESC_NULLS_LAST example: DESC - name: periodType in: query description: Inventory history period granularity. required: true schema: type: string enum: - WEEKLY - MONTHLY - name: minStartDate in: query description: Minimum inclusive history start date. required: false schema: type: string format: date - name: maxStartDate in: query description: Maximum inclusive history start date. required: false schema: type: string format: date responses: '200': description: Paged store inventory health history results content: application/json: schema: $ref: '#/components/schemas/LimitOffsetResponseStoreHistoryResponse' '403': description: API key does not include inventory:read '401': description: Missing, malformed, or invalid API key '400': description: Invalid query parameter /external/v1/inventory-health/pos-brands: get: tags: - Inventory Health summary: List POS brand inventory health description: Returns POS brand inventory health metrics for the API key organization. Results are always separated by store. Requires inventory:read. operationId: getPosBrandInventoryHealths parameters: - name: offset in: query description: Zero-based result offset for pagination. required: false schema: minimum: 0 type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of inventory health rows to return. Maximum is 500. required: false schema: maximum: 500 minimum: 0 type: integer format: int32 default: 100 example: 100 - name: storeIds in: query description: Store UUID filters. Pass repeated query parameters, for example storeIds=id1&storeIds=id2. required: false schema: type: array items: type: string format: uuid example: 11111111-1111-1111-1111-111111111111 - name: brandIds in: query description: POS brand ID filters. Pass repeated query parameters, for example brandIds=1&brandIds=2. required: false schema: type: array items: type: integer format: int32 example: 99 - name: categoryIds in: query description: POS category ID filters. Pass repeated query parameters, for example categoryIds=1&categoryIds=2. required: false schema: type: array items: type: integer format: int32 example: 42 - name: search in: query description: Search text matched against the fields returned by the route. required: false schema: type: string - name: includePercentShares in: query description: Whether to include percent-share fields. required: false schema: type: boolean example: false - name: sortTarget in: query description: Field to sort by. required: false schema: type: string enum: - UNITS_PER_DAY - UPDATED_AT - PERCENT_SHARE_OF_PROFIT - PERCENT_SHARE_OF_AGED_INVENTORY_COST - PERCENT_SHARE_OF_DOLLARS_SOLD - PERCENT_SHARE_OF_UNITS_SOLD example: UNITS_PER_DAY - name: sortDirection in: query description: Sort direction. Prefer ASC or DESC; lowercase values are deprecated aliases. required: false schema: type: string enum: - asc - desc - ASC - DESC - ASC_NULLS_FIRST - ASC_NULLS_LAST - DESC_NULLS_FIRST - DESC_NULLS_LAST example: DESC - name: posBrandIds in: query description: Optional target posBrands to filter responses required: false schema: type: array items: type: integer format: int32 example: 332 responses: '200': description: Paged POS brand inventory health results content: application/json: schema: $ref: '#/components/schemas/LimitOffsetResponsePosBrandResponse' '403': description: API key does not include inventory:read '401': description: Missing, malformed, or invalid API key '400': description: Invalid query parameter /external/v1/inventory-health/pos-brands/history: get: tags: - Inventory Health summary: List POS brand inventory health history description: Returns historical POS brand inventory health metrics for the API key organization. Results are always separated by store. Requires inventory:read. operationId: getPosBrandInventoryHealthHistory parameters: - name: offset in: query description: Zero-based result offset for pagination. required: false schema: minimum: 0 type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of inventory health rows to return. Maximum is 500. required: false schema: maximum: 500 minimum: 0 type: integer format: int32 default: 100 example: 100 - name: storeIds in: query description: Store UUID filters. Pass repeated query parameters, for example storeIds=id1&storeIds=id2. required: false schema: type: array items: type: string format: uuid example: 11111111-1111-1111-1111-111111111111 - name: search in: query description: Search text matched against the fields returned by the route. required: false schema: type: string - name: sortTarget in: query description: Field to sort by. required: false schema: type: string enum: - START_DATE - UNITS_PER_DAY - UPDATED_AT example: START_DATE - name: sortDirection in: query description: Sort direction. Prefer ASC or DESC; lowercase values are deprecated aliases. required: false schema: type: string enum: - asc - desc - ASC - DESC - ASC_NULLS_FIRST - ASC_NULLS_LAST - DESC_NULLS_FIRST - DESC_NULLS_LAST example: DESC - name: periodType in: query description: Inventory history period granularity. required: true schema: type: string enum: - WEEKLY - MONTHLY - name: minStartDate in: query description: Minimum inclusive history start date. required: false schema: type: string format: date - name: maxStartDate in: query description: Maximum inclusive history start date. required: false schema: type: string format: date - name: posBrandIds in: query description: Optional target posBrands to filter responses required: false schema: type: array items: type: integer format: int32 example: 332 responses: '403': description: API key does not include inventory:read '401': description: Missing, malformed, or invalid API key '200': description: Paged POS brand inventory health history results content: application/json: schema: $ref: '#/components/schemas/LimitOffsetResponsePosBrandHistoryResponse' '400': description: Invalid query parameter /external/v1/inventory-health/categories: get: tags: - Inventory Health summary: List category inventory health description: Returns POS category inventory health metrics for the API key organization. Results are always separated by store. Requires inventory:read. operationId: getCategoryInventoryHealths parameters: - name: offset in: query description: Zero-based result offset for pagination. required: false schema: minimum: 0 type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of inventory health rows to return. Maximum is 500. required: false schema: maximum: 500 minimum: 0 type: integer format: int32 default: 100 example: 100 - name: storeIds in: query description: Store UUID filters. Pass repeated query parameters, for example storeIds=id1&storeIds=id2. required: false schema: type: array items: type: string format: uuid example: 11111111-1111-1111-1111-111111111111 - name: brandIds in: query description: POS brand ID filters. Pass repeated query parameters, for example brandIds=1&brandIds=2. required: false schema: type: array items: type: integer format: int32 example: 99 - name: categoryIds in: query description: POS category ID filters. Pass repeated query parameters, for example categoryIds=1&categoryIds=2. required: false schema: type: array items: type: integer format: int32 example: 42 - name: search in: query description: Search text matched against the fields returned by the route. required: false schema: type: string - name: includePercentShares in: query description: Whether to include percent-share fields. required: false schema: type: boolean example: false - name: sortTarget in: query description: Field to sort by. required: false schema: type: string enum: - UNITS_PER_DAY - UPDATED_AT - PERCENT_SHARE_OF_PROFIT - PERCENT_SHARE_OF_AGED_INVENTORY_COST - PERCENT_SHARE_OF_DOLLARS_SOLD - PERCENT_SHARE_OF_UNITS_SOLD example: UNITS_PER_DAY - name: sortDirection in: query description: Sort direction. Prefer ASC or DESC; lowercase values are deprecated aliases. required: false schema: type: string enum: - asc - desc - ASC - DESC - ASC_NULLS_FIRST - ASC_NULLS_LAST - DESC_NULLS_FIRST - DESC_NULLS_LAST example: DESC responses: '200': description: Paged category inventory health results content: application/json: schema: $ref: '#/components/schemas/LimitOffsetResponseCategoryResponse' '403': description: API key does not include inventory:read '401': description: Missing, malformed, or invalid API key '400': description: Invalid query parameter /external/v1/inventory-health/categories/history: get: tags: - Inventory Health summary: List category inventory health history description: Returns historical POS category inventory health metrics for the API key organization. Results are always separated by store. Requires inventory:read. operationId: getCategoryInventoryHealthHistories parameters: - name: offset in: query description: Zero-based result offset for pagination. required: false schema: minimum: 0 type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of inventory health rows to return. Maximum is 500. required: false schema: maximum: 500 minimum: 0 type: integer format: int32 default: 100 example: 100 - name: storeIds in: query description: Store UUID filters. Pass repeated query parameters, for example storeIds=id1&storeIds=id2. required: false schema: type: array items: type: string format: uuid example: 11111111-1111-1111-1111-111111111111 - name: search in: query description: Search text matched against the fields returned by the route. required: false schema: type: string - name: sortTarget in: query description: Field to sort by. required: false schema: type: string enum: - START_DATE - UNITS_PER_DAY - UPDATED_AT example: START_DATE - name: sortDirection in: query description: Sort direction. Prefer ASC or DESC; lowercase values are deprecated aliases. required: false schema: type: string enum: - asc - desc - ASC - DESC - ASC_NULLS_FIRST - ASC_NULLS_LAST - DESC_NULLS_FIRST - DESC_NULLS_LAST example: DESC - name: periodType in: query description: Inventory history period granularity. required: true schema: type: string enum: - WEEKLY - MONTHLY - name: minStartDate in: query description: Minimum inclusive history start date. required: false schema: type: string format: date - name: maxStartDate in: query description: Maximum inclusive history start date. required: false schema: type: string format: date - name: categoryIds in: query description: Optional target categories to filter responses required: false schema: type: array items: type: integer format: int32 example: 1 responses: '403': description: API key does not include inventory:read '401': description: Missing, malformed, or invalid API key '200': description: Paged category inventory health history results content: application/json: schema: $ref: '#/components/schemas/LimitOffsetResponseCategoryHistoryResponse' '400': description: Invalid query parameter components: schemas: PosBrandHistoryResponse: type: object properties: startDate: type: string description: Inclusive start date for this history period. format: date example: '2026-01-05' endDate: type: string description: Inclusive end date for this history period. format: date example: '2026-01-11' periodType: type: string description: Inventory history period granularity. example: WEEKLY enum: - WEEKLY - MONTHLY posBrandId: type: integer description: POS brand ID. format: int32 example: 99 posBrandName: type: string description: POS brand name. example: Blue River predictedDaysOnHand: type: integer description: Predicted days on hand based on inventory and sales velocity. format: int32 createdAt: type: string description: Creation timestamp for the underlying inventory health data. format: date-time updatedAt: type: string description: Most recent update timestamp for the underlying inventory health data. format: date-time unitsSold: type: integer description: Units sold in the projected inventory health period. format: int32 example: 120 dollarsSold: type: number description: Sales dollars in the projected inventory health period. format: double example: 3200.0 discountDollars: type: number description: Discount dollars in the projected inventory health period. format: double example: 150.0 averageDiscountPercent: type: number description: Average discount percentage. format: double example: 4.5 averageMargin: type: number description: Average margin percentage. format: double example: 42.5 inventoryCost: type: number description: Current inventory cost dollars. format: double example: 1200.0 agedInventoryCost: type: number description: Cost dollars for inventory aged 90 or more days. format: double example: 300.0 storeName: type: string description: Store/location display name. example: Downtown storeId: type: string description: Store/location UUID for this inventory health row. format: uuid totalProfit: type: number description: Total profit dollars. format: double example: 875.25 percentShareOfProfit: type: number description: Percent share of total profit for the current result set. format: double percentShareOfAgedInventoryCost: type: number description: Percent share of aged inventory cost for the current result set. format: double percentShareOfDollarsSold: type: number description: Percent share of dollars sold for the current result set. format: double percentShareOfUnitsSold: type: number description: Percent share of units sold for the current result set. format: double unitsInStock: type: integer description: Current inventory units on hand. format: int32 example: 80 sellableUnitsInStock: type: integer description: Current sellable inventory units on hand. format: int32 example: 72 unitsAged0To30: type: integer description: Current inventory units aged 0 to 30 days. format: int32 example: 25 unitsAged31To60: type: integer description: Current inventory units aged 31 to 60 days. format: int32 example: 20 unitsAged61To90: type: integer description: Current inventory units aged 61 to 90 days. format: int32 example: 15 unitsAged90Plus: type: integer description: Current inventory units aged 90 or more days. format: int32 example: 10 unitsPerDay: type: number description: Average units sold per day. format: double example: 6.25 description: Records for the current page. LimitOffsetResponseCategoryHistoryResponse: type: object properties: limit: type: integer description: Maximum number of records requested for this page. format: int32 example: 100 offset: type: integer description: Zero-based result offset used for this page. format: int32 example: 0 totalCount: type: integer description: Total number of matching records before pagination is applied. format: int32 example: 250 results: type: array description: Records for the current page. items: $ref: '#/components/schemas/CategoryHistoryResponse' hasMore: type: boolean description: True when more records are available after this page. example: true LimitOffsetResponseStoreHistoryResponse: type: object properties: limit: type: integer description: Maximum number of records requested for this page. format: int32 example: 100 offset: type: integer description: Zero-based result offset used for this page. format: int32 example: 0 totalCount: type: integer description: Total number of matching records before pagination is applied. format: int32 example: 250 results: type: array description: Records for the current page. items: $ref: '#/components/schemas/StoreHistoryResponse' hasMore: type: boolean description: True when more records are available after this page. example: true LimitOffsetResponsePosBrandResponse: type: object properties: limit: type: integer description: Maximum number of records requested for this page. format: int32 example: 100 offset: type: integer description: Zero-based result offset used for this page. format: int32 example: 0 totalCount: type: integer description: Total number of matching records before pagination is applied. format: int32 example: 250 results: type: array description: Records for the current page. items: $ref: '#/components/schemas/PosBrandResponse' hasMore: type: boolean description: True when more records are available after this page. example: true LimitOffsetResponseStoreResponse: type: object properties: limit: type: integer description: Maximum number of records requested for this page. format: int32 example: 100 offset: type: integer description: Zero-based result offset used for this page. format: int32 example: 0 totalCount: type: integer description: Total number of matching records before pagination is applied. format: int32 example: 250 results: type: array description: Records for the current page. items: $ref: '#/components/schemas/StoreResponse' hasMore: type: boolean description: True when more records are available after this page. example: true StoreResponse: type: object properties: name: type: string description: Full display name of the store/location. example: Downtown Retail id: type: string description: Store/location UUID. format: uuid example: 11111111-1111-1111-1111-111111111111 type: type: string description: Store/location type. example: RETAIL enum: - RETAIL - DISTRIBUTION_CENTER - CULTIVATION - MANUFACTURING createdAt: type: string description: Timestamp when the store/location was created. format: date-time example: '2026-01-01T00:00:00Z' stateCode: type: string description: Two-letter state code for the store/location. example: CA fulfilledById: type: string description: Distribution center UUID that fulfills this location, when a fulfillment relationship exists. format: uuid fulfilledByStoreName: type: string description: Name of the fulfillment location, when configured. description: Records for the current page. CategoryResponse: type: object properties: categoryId: type: integer description: POS category ID. format: int32 example: 42 categoryName: type: string description: POS category name. example: Flower predictedDaysOnHand: type: integer description: Predicted days on hand based on inventory and sales velocity. format: int32 createdAt: type: string description: Creation timestamp for the underlying inventory health data. format: date-time updatedAt: type: string description: Most recent update timestamp for the underlying inventory health data. format: date-time unitsSold: type: integer description: Units sold in the projected inventory health period. format: int32 example: 120 dollarsSold: type: number description: Sales dollars in the projected inventory health period. format: double example: 3200.0 discountDollars: type: number description: Discount dollars in the projected inventory health period. format: double example: 150.0 averageDiscountPercent: type: number description: Average discount percentage. format: double example: 4.5 averageMargin: type: number description: Average margin percentage. format: double example: 42.5 inventoryCost: type: number description: Current inventory cost dollars. format: double example: 1200.0 agedInventoryCost: type: number description: Cost dollars for inventory aged 90 or more days. format: double example: 300.0 storeName: type: string description: Store/location display name. example: Downtown storeId: type: string description: Store/location UUID for this inventory health row. format: uuid totalProfit: type: number description: Total profit dollars. format: double example: 875.25 percentShareOfProfit: type: number description: Percent share of total profit for the current result set. format: double percentShareOfAgedInventoryCost: type: number description: Percent share of aged inventory cost for the current result set. format: double percentShareOfDollarsSold: type: number description: Percent share of dollars sold for the current result set. format: double percentShareOfUnitsSold: type: number description: Percent share of units sold for the current result set. format: double unitsInStock: type: integer description: Current inventory units on hand. format: int32 example: 80 sellableUnitsInStock: type: integer description: Current sellable inventory units on hand. format: int32 example: 72 unitsAged0To30: type: integer description: Current inventory units aged 0 to 30 days. format: int32 example: 25 unitsAged31To60: type: integer description: Current inventory units aged 31 to 60 days. format: int32 example: 20 unitsAged61To90: type: integer description: Current inventory units aged 61 to 90 days. format: int32 example: 15 unitsAged90Plus: type: integer description: Current inventory units aged 90 or more days. format: int32 example: 10 unitsPerDay: type: number description: Average units sold per day. format: double example: 6.25 description: Records for the current page. StoreHistoryResponse: type: object properties: startDate: type: string description: Inclusive start date for this history period. format: date example: '2026-01-05' endDate: type: string description: Inclusive end date for this history period. format: date example: '2026-01-11' periodType: type: string description: Inventory history period granularity. example: WEEKLY enum: - WEEKLY - MONTHLY predictedDaysOnHand: type: integer description: Predicted days on hand based on inventory and sales velocity. format: int32 createdAt: type: string description: Creation timestamp for the underlying inventory health data. format: date-time updatedAt: type: string description: Most recent update timestamp for the underlying inventory health data. format: date-time unitsSold: type: integer description: Units sold in the projected inventory health period. format: int32 example: 120 dollarsSold: type: number description: Sales dollars in the projected inventory health period. format: double example: 3200.0 discountDollars: type: number description: Discount dollars in the projected inventory health period. format: double example: 150.0 averageDiscountPercent: type: number description: Average discount percentage. format: double example: 4.5 averageMargin: type: number description: Average margin percentage. format: double example: 42.5 inventoryCost: type: number description: Current inventory cost dollars. format: double example: 1200.0 agedInventoryCost: type: number description: Cost dollars for inventory aged 90 or more days. format: double example: 300.0 storeName: type: string description: Store/location display name. example: Downtown storeId: type: string description: Store/location UUID for this inventory health row. format: uuid totalProfit: type: number description: Total profit dollars. format: double example: 875.25 percentShareOfProfit: type: number description: Percent share of total profit for the current result set. format: double percentShareOfAgedInventoryCost: type: number description: Percent share of aged inventory cost for the current result set. format: double percentShareOfDollarsSold: type: number description: Percent share of dollars sold for the current result set. format: double percentShareOfUnitsSold: type: number description: Percent share of units sold for the current result set. format: double unitsInStock: type: integer description: Current inventory units on hand. format: int32 example: 80 sellableUnitsInStock: type: integer description: Current sellable inventory units on hand. format: int32 example: 72 unitsAged0To30: type: integer description: Current inventory units aged 0 to 30 days. format: int32 example: 25 unitsAged31To60: type: integer description: Current inventory units aged 31 to 60 days. format: int32 example: 20 unitsAged61To90: type: integer description: Current inventory units aged 61 to 90 days. format: int32 example: 15 unitsAged90Plus: type: integer description: Current inventory units aged 90 or more days. format: int32 example: 10 unitsPerDay: type: number description: Average units sold per day. format: double example: 6.25 description: Records for the current page. LimitOffsetResponseCategoryResponse: type: object properties: limit: type: integer description: Maximum number of records requested for this page. format: int32 example: 100 offset: type: integer description: Zero-based result offset used for this page. format: int32 example: 0 totalCount: type: integer description: Total number of matching records before pagination is applied. format: int32 example: 250 results: type: array description: Records for the current page. items: $ref: '#/components/schemas/CategoryResponse' hasMore: type: boolean description: True when more records are available after this page. example: true PosBrandResponse: type: object properties: name: type: string description: POS brand display name. example: Acme id: type: integer description: Happy Buyers POS brand ID. format: int32 example: 42 productCount: type: integer description: Number of products currently associated with this POS brand. format: int32 example: 17 mappedUniversalBrandId: type: integer description: Mapped universal brand ID, when this POS brand has a mapping. format: int32 posIdentifier: type: string description: Brand identifier from the source POS system. example: brand-123 mappedUniversalBrandName: type: string description: Mapped universal brand name, or an empty string when unmapped. description: Records for the current page. LimitOffsetResponsePosBrandHistoryResponse: type: object properties: limit: type: integer description: Maximum number of records requested for this page. format: int32 example: 100 offset: type: integer description: Zero-based result offset used for this page. format: int32 example: 0 totalCount: type: integer description: Total number of matching records before pagination is applied. format: int32 example: 250 results: type: array description: Records for the current page. items: $ref: '#/components/schemas/PosBrandHistoryResponse' hasMore: type: boolean description: True when more records are available after this page. example: true CategoryHistoryResponse: type: object properties: categoryId: type: integer description: POS category ID. format: int32 example: 42 startDate: type: string description: Inclusive start date for this history period. format: date example: '2026-01-05' endDate: type: string description: Inclusive end date for this history period. format: date example: '2026-01-11' periodType: type: string description: Inventory history period granularity. example: WEEKLY enum: - WEEKLY - MONTHLY categoryName: type: string description: POS category name. example: Flower predictedDaysOnHand: type: integer description: Predicted days on hand based on inventory and sales velocity. format: int32 createdAt: type: string description: Creation timestamp for the underlying inventory health data. format: date-time updatedAt: type: string description: Most recent update timestamp for the underlying inventory health data. format: date-time unitsSold: type: integer description: Units sold in the projected inventory health period. format: int32 example: 120 dollarsSold: type: number description: Sales dollars in the projected inventory health period. format: double example: 3200.0 discountDollars: type: number description: Discount dollars in the projected inventory health period. format: double example: 150.0 averageDiscountPercent: type: number description: Average discount percentage. format: double example: 4.5 averageMargin: type: number description: Average margin percentage. format: double example: 42.5 inventoryCost: type: number description: Current inventory cost dollars. format: double example: 1200.0 agedInventoryCost: type: number description: Cost dollars for inventory aged 90 or more days. format: double example: 300.0 storeName: type: string description: Store/location display name. example: Downtown storeId: type: string description: Store/location UUID for this inventory health row. format: uuid totalProfit: type: number description: Total profit dollars. format: double example: 875.25 percentShareOfProfit: type: number description: Percent share of total profit for the current result set. format: double percentShareOfAgedInventoryCost: type: number description: Percent share of aged inventory cost for the current result set. format: double percentShareOfDollarsSold: type: number description: Percent share of dollars sold for the current result set. format: double percentShareOfUnitsSold: type: number description: Percent share of units sold for the current result set. format: double unitsInStock: type: integer description: Current inventory units on hand. format: int32 example: 80 sellableUnitsInStock: type: integer description: Current sellable inventory units on hand. format: int32 example: 72 unitsAged0To30: type: integer description: Current inventory units aged 0 to 30 days. format: int32 example: 25 unitsAged31To60: type: integer description: Current inventory units aged 31 to 60 days. format: int32 example: 20 unitsAged61To90: type: integer description: Current inventory units aged 61 to 90 days. format: int32 example: 15 unitsAged90Plus: type: integer description: Current inventory units aged 90 or more days. format: int32 example: 10 unitsPerDay: type: number description: Average units sold per day. format: double example: 6.25 description: Records for the current page. securitySchemes: ApiKeyAuth: type: apiKey description: External API key issued by Happy Buyers. Send the key in the hca-api-key header. name: hca-api-key in: header