@@ -1,394 +0,0 @@
# Brand Intelligence API
## Endpoint
```
GET /api/analytics/v2/brand/:name/intelligence
```
## Query Parameters
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `window` | `7d\|30d\|90d` | `30d` | Time window for trend calculations |
| `state` | string | - | Filter by state code (e.g., `AZ` ) |
| `category` | string | - | Filter by category (e.g., `Flower` ) |
## Response Payload Schema
``` typescript
interface BrandIntelligenceResult {
brand_name : string ;
window : '7d' | '30d' | '90d' ;
generated_at : string ; // ISO timestamp when data was computed
performance_snapshot : PerformanceSnapshot ;
alerts : Alerts ;
sku_performance : SkuPerformance [ ] ;
retail_footprint : RetailFootprint ;
competitive_landscape : CompetitiveLandscape ;
inventory_health : InventoryHealth ;
promo_performance : PromoPerformance ;
}
```
---
## Section 1: Performance Snapshot
Summary cards with key brand metrics.
``` typescript
interface PerformanceSnapshot {
active_skus : number ; // Total products in catalog
total_revenue_30d : number | null ; // Estimated from qty × price
total_stores : number ; // Active retail partners
new_stores_30d : number ; // New distribution in window
market_share : number | null ; // % of category SKUs
avg_wholesale_price : number | null ;
price_position : 'premium' | 'value' | 'competitive' ;
}
```
**UI Label Mapping: **
| Field | User-Facing Label | Helper Text |
|-------|-------------------|-------------|
| `active_skus` | Active Products | X total in catalog |
| `total_revenue_30d` | Monthly Revenue | Estimated from sales |
| `total_stores` | Retail Distribution | Active retail partners |
| `new_stores_30d` | New Opportunities | X new in last 30 days |
| `market_share` | Category Position | % of category |
| `avg_wholesale_price` | Avg Wholesale | Per unit |
| `price_position` | Pricing Tier | Premium/Value/Market Rate |
---
## Section 2: Alerts
Issues requiring attention.
``` typescript
interface Alerts {
lost_stores_30d_count : number ;
lost_skus_30d_count : number ;
competitor_takeover_count : number ;
avg_oos_duration_days : number | null ;
avg_reorder_lag_days : number | null ;
items : AlertItem [ ] ;
}
interface AlertItem {
type : 'lost_store' | 'delisted_sku' | 'shelf_loss' | 'extended_oos' ;
severity : 'critical' | 'warning' ;
store_name? : string ;
product_name? : string ;
competitor_brand? : string ;
days_since? : number ;
state_code? : string ;
}
```
**UI Label Mapping: **
| Field | User-Facing Label |
|-------|-------------------|
| `lost_stores_30d_count` | Accounts at Risk |
| `lost_skus_30d_count` | Delisted SKUs |
| `competitor_takeover_count` | Shelf Losses |
| `avg_oos_duration_days` | Avg Stockout Length |
| `avg_reorder_lag_days` | Avg Restock Time |
| `severity: critical` | Urgent |
| `severity: warning` | Watch |
---
## Section 3: SKU Performance (Product Velocity)
How fast each SKU sells.
``` typescript
interface SkuPerformance {
store_product_id : number ;
product_name : string ;
category : string | null ;
daily_velocity : number ; // Units/day estimate
velocity_status : 'hot' | 'steady' | 'slow' | 'stale' ;
retail_price : number | null ;
on_sale : boolean ;
stores_carrying : number ;
stock_status : 'in_stock' | 'low_stock' | 'out_of_stock' ;
}
```
**UI Label Mapping: **
| Field | User-Facing Label |
|-------|-------------------|
| `daily_velocity` | Daily Rate |
| `velocity_status` | Momentum |
| `velocity_status: hot` | Hot |
| `velocity_status: steady` | Steady |
| `velocity_status: slow` | Slow |
| `velocity_status: stale` | Stale |
| `retail_price` | Retail Price |
| `on_sale` | Promo (badge) |
**Velocity Thresholds: **
- `hot` : >= 5 units/day
- `steady` : >= 1 unit/day
- `slow` : >= 0.1 units/day
- `stale` : < 0.1 units/day
---
## Section 4: Retail Footprint
Store placement and coverage.
``` typescript
interface RetailFootprint {
total_stores : number ;
in_stock_count : number ;
out_of_stock_count : number ;
penetration_by_region : RegionPenetration [ ] ;
whitespace_stores : WhitespaceStore [ ] ;
}
interface RegionPenetration {
state_code : string ;
store_count : number ;
percent_reached : number ; // % of state's dispensaries
in_stock : number ;
out_of_stock : number ;
}
interface WhitespaceStore {
store_id : number ;
store_name : string ;
state_code : string ;
city : string | null ;
category_fit : number ; // How many competing brands they carry
competitor_brands : string [ ] ;
}
```
**UI Label Mapping: **
| Field | User-Facing Label |
|-------|-------------------|
| `penetration_by_region` | Market Coverage by Region |
| `percent_reached` | X% reached |
| `in_stock` | X stocked |
| `out_of_stock` | X out |
| `whitespace_stores` | Expansion Opportunities |
| `category_fit` | X fit |
---
## Section 5: Competitive Landscape
Market positioning vs competitors.
``` typescript
interface CompetitiveLandscape {
brand_price_position : 'premium' | 'value' | 'competitive' ;
market_share_trend : MarketSharePoint [ ] ;
competitors : Competitor [ ] ;
head_to_head_skus : HeadToHead [ ] ;
}
interface MarketSharePoint {
date : string ;
share_percent : number ;
}
interface Competitor {
brand_name : string ;
store_overlap_percent : number ;
price_position : 'premium' | 'value' | 'competitive' ;
avg_price : number | null ;
sku_count : number ;
}
interface HeadToHead {
product_name : string ;
brand_price : number ;
competitor_brand : string ;
competitor_price : number ;
price_diff_percent : number ;
}
```
**UI Label Mapping: **
| Field | User-Facing Label |
|-------|-------------------|
| `price_position: premium` | Premium Tier |
| `price_position: value` | Value Leader |
| `price_position: competitive` | Market Rate |
| `market_share_trend` | Share of Shelf Trend |
| `head_to_head_skus` | Price Comparison |
| `store_overlap_percent` | X% store overlap |
---
## Section 6: Inventory Health
Stock projections and risk levels.
``` typescript
interface InventoryHealth {
critical_count : number ; // <7 days stock
warning_count : number ; // 7-14 days stock
healthy_count : number ; // 14-90 days stock
overstocked_count : number ; // >90 days stock
skus : InventorySku [ ] ;
overstock_alert : OverstockItem [ ] ;
}
interface InventorySku {
store_product_id : number ;
product_name : string ;
store_name : string ;
days_of_stock : number | null ;
risk_level : 'critical' | 'elevated' | 'moderate' | 'healthy' ;
current_quantity : number | null ;
daily_sell_rate : number | null ;
}
interface OverstockItem {
product_name : string ;
store_name : string ;
excess_units : number ;
days_of_stock : number ;
}
```
**UI Label Mapping: **
| Field | User-Facing Label |
|-------|-------------------|
| `risk_level: critical` | Reorder Now |
| `risk_level: elevated` | Low Stock |
| `risk_level: moderate` | Monitor |
| `risk_level: healthy` | Healthy |
| `critical_count` | Urgent (<7 days) |
| `warning_count` | Low (7-14 days) |
| `overstocked_count` | Excess (>90 days) |
| `days_of_stock` | X days remaining |
| `overstock_alert` | Overstock Alert |
| `excess_units` | X excess units |
---
## Section 7: Promotion Effectiveness
How promotions impact sales.
``` typescript
interface PromoPerformance {
avg_baseline_velocity : number | null ;
avg_promo_velocity : number | null ;
avg_velocity_lift : number | null ; // % increase during promo
avg_efficiency_score : number | null ; // ROI proxy
promotions : Promotion [ ] ;
}
interface Promotion {
product_name : string ;
store_name : string ;
status : 'active' | 'scheduled' | 'ended' ;
start_date : string ;
end_date : string | null ;
regular_price : number ;
promo_price : number ;
discount_percent : number ;
baseline_velocity : number | null ;
promo_velocity : number | null ;
velocity_lift : number | null ;
efficiency_score : number | null ;
}
```
**UI Label Mapping: **
| Field | User-Facing Label |
|-------|-------------------|
| `avg_baseline_velocity` | Normal Rate |
| `avg_promo_velocity` | During Promos |
| `avg_velocity_lift` | Avg Sales Lift |
| `avg_efficiency_score` | ROI Score |
| `velocity_lift` | Sales Lift |
| `efficiency_score` | ROI Score |
| `status: active` | Live |
| `status: scheduled` | Scheduled |
| `status: ended` | Ended |
---
## Example Queries
### Get full payload
``` javascript
const response = await fetch ( '/api/analytics/v2/brand/Wyld/intelligence?window=30d' ) ;
const data = await response . json ( ) ;
```
### Extract summary cards (flattened)
``` javascript
const { performance _snapshot : ps , alerts } = data ;
const summaryCards = {
activeProducts : ps . active _skus ,
monthlyRevenue : ps . total _revenue _30d ,
retailDistribution : ps . total _stores ,
newOpportunities : ps . new _stores _30d ,
categoryPosition : ps . market _share ,
avgWholesale : ps . avg _wholesale _price ,
pricingTier : ps . price _position ,
accountsAtRisk : alerts . lost _stores _30d _count ,
delistedSkus : alerts . lost _skus _30d _count ,
shelfLosses : alerts . competitor _takeover _count ,
} ;
```
### Get top 10 fastest selling SKUs
``` javascript
const topSkus = data . sku _performance
. filter ( sku => sku . velocity _status === 'hot' || sku . velocity _status === 'steady' )
. sort ( ( a , b ) => b . daily _velocity - a . daily _velocity )
. slice ( 0 , 10 ) ;
```
### Get critical inventory alerts only
``` javascript
const criticalInventory = data . inventory _health . skus
. filter ( sku => sku . risk _level === 'critical' ) ;
```
### Get states with <50% penetration
``` javascript
const underPenetrated = data . retail _footprint . penetration _by _region
. filter ( region => region . percent _reached < 50 )
. sort ( ( a , b ) => a . percent _reached - b . percent _reached ) ;
```
### Get active promotions with positive lift
``` javascript
const effectivePromos = data . promo _performance . promotions
. filter ( p => p . status === 'active' && p . velocity _lift > 0 )
. sort ( ( a , b ) => b . velocity _lift - a . velocity _lift ) ;
```
### Build chart data for market share trend
``` javascript
const chartData = data . competitive _landscape . market _share _trend . map ( point => ( {
x : new Date ( point . date ) ,
y : point . share _percent ,
} ) ) ;
```
---
## Notes for Frontend Implementation
1. **All fields are snake_case ** - transform to camelCase if needed
2. **Null values are possible ** - handle gracefully in UI
3. **Arrays may be empty ** - show appropriate empty states
4. **Timestamps are ISO format ** - parse with `new Date()`
5. **Percentages are already computed ** - no need to multiply by 100
6. **The `window` parameter affects trend calculations ** - 7d/30d/90d