Optimization Data API
Labor optimization metrics and goals for schedule planning
Returns weekly optimization data including sales, labor costs, and goal progress. Used for labor variance checking and schedule optimization.
Endpoints
GET /api/analytics/optimization
GET /api/analytics/goalsQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
teamId | string | ✅ | Team/organization identifier |
weekOf | string | ✅ | ISO date of Saturday starting the week |
locationId | string | ❌ | Optional location filter |
Optimization Response Schema
{
weekLabel: string;
summary: {
totalSales: number; // finite, nonnegative
totalLaborCost: number; // finite, nonnegative
laborPctFraction: number | null; // ratio, null with reason when unavailable
laborPctReason: string | null;
targetLaborPct?: number; // presentation target, 0-100
splh: number | null; // USD/hour, ratio
splhReason: string | null;
targetSplh?: number; // USD/hour
};
salesByCategory?: Array<{ // defaults to [] if not provided
day: string;
block: string;
food: number; // finite, nonnegative
beverage: number; // finite, nonnegative
other: number; // finite, nonnegative
total: number; // finite, nonnegative
}>;
laborByCategory?: Array<{ // defaults to [] if not provided
day: string;
fohHours: number; // finite, nonnegative
bohHours: number; // finite, nonnegative
naHours: number; // finite, nonnegative
totalHours: number; // finite, nonnegative
cost: number; // finite, nonnegative
laborPctFraction: number | null;
laborPctReason: string | null;
}>;
dailySummary?: Array<{ // defaults to [] if not provided
day: string;
sales: number; // finite, nonnegative
laborCost: number; // finite, nonnegative
laborPctFraction: number | null;
laborPctReason: string | null;
splh: number | null;
splhReason: string | null;
servedGuests?: number; // integer, nonnegative
goalsMet?: boolean;
}>;
weeklySummary?: { // optional
totalSales: number; // finite, nonnegative
totalLaborCost: number; // finite, nonnegative
avgLaborPctFraction: number | null;
avgLaborPctReason: string | null;
avgSplh: number | null; // diagnostic daily mean, not weekly KPI
goalsMetPercent?: number;
topDay?: string;
worstDay?: string;
};
}Goals Response Schema
{
goals: Array<{
dayOfWeek: number; // integer 0-6 (0 = Saturday)
salesGoal: number; // finite, nonnegative
laborPctTarget: number; // finite, nonnegative
splhTarget: number; // finite, nonnegative
}>;
}Example Request
curl -X GET "https://analytics.example.com/api/analytics/optimization?teamId=team123&weekOf=2026-05-16&locationId=loc456" \
-H "Authorization: Bearer YOUR_API_KEY"Example Response
{
"weekLabel": "May 11-17, 2026",
"summary": {
"totalSales": 45230.00,
"totalLaborCost": 12500.00,
"laborPctFraction": 0.276,
"laborPctReason": null,
"splh": 142.50,
"splhReason": null
},
"salesByCategory": [
{
"day": "Monday",
"block": "Dinner",
"food": 2500.00,
"beverage": 1200.00,
"other": 300.00,
"total": 4000.00
}
],
"laborByCategory": [
{
"day": "Monday",
"fohHours": 32.5,
"bohHours": 28.0,
"naHours": 4.0,
"totalHours": 64.5,
"cost": 1800.00,
"laborPctFraction": 0.265,
"laborPctReason": null
}
],
"dailySummary": [
{
"day": "Monday",
"sales": 6500.00,
"laborCost": 1800.00,
"laborPctFraction": 0.277,
"laborPctReason": null,
"splh": 140.00,
"splhReason": null,
"goalsMet": true
}
],
"weeklySummary": {
"totalSales": 45230.00,
"totalLaborCost": 12500.00,
"avgLaborPctFraction": 0.276,
"avgLaborPctReason": null,
"avgSplh": 142.50,
"goalsMetPercent": 71.4,
"topDay": "Saturday",
"worstDay": "Tuesday"
}
}Goals Example Response
{
"goals": [
{
"dayOfWeek": 0,
"salesGoal": 5000.00,
"laborPctTarget": 28.0,
"splhTarget": 135.00
}
]
}Cache TTL
- Redis cache: 15 minutes
- Reconfiguration: On webhook events or scheduled sync
Client Usage
import { getOptimizationData, getGoalsFromApi } from '@repo/optimization';
// Get weekly optimization data
const optimization = await getOptimizationData({
teamId: 'team123',
weekOf: '2026-05-16',
locationId: 'loc456'
});
// Get optimization goals
const goals = await getGoalsFromApi({
teamId: 'team123',
locationId: 'loc456'
});Error Responses
| Status | Description |
|---|---|
401 | Missing or invalid API key |
400 | Invalid query parameters |
503 | Circuit breaker open |
Related Files
| File | Purpose |
|---|---|
packages/optimization/queries.ts | Server-side optimization data queries |
packages/optimization/fill-rate.ts | Schedule fill-rate calculation logic |
packages/daypart-readiness/service.ts | Daypart readiness and sales-line resolution |