Integration Troubleshooting
This guide helps you diagnose and resolve common integration issues with Eaternity Forecast.
Authentication Issues
API Key Not Working
Symptoms:
- 401 Unauthorized responses
- "Authentication failed" errors
Common Causes & Solutions:
1. Incorrect API Key Format
Problem: Extra spaces or characters in API key
Solution:
# Wrong (trailing space)
API_KEY="sk_live_abc123 "
# Correct (no extra spaces)
API_KEY="sk_live_abc123"
# Test authentication
curl -X GET "https://api.eaternity.org/v1/forecast/ping" \
-H "Authorization: Bearer $API_KEY"
2. Using Sandbox Key in Production
Problem: Attempting to use sandbox API key with production URL
Solution:
# Sandbox key (starts with sk_sandbox_)
sk_sandbox_abc123 → Use with https://sandbox-api.eaternity.org
# Production key (starts with sk_live_)
sk_live_abc123 → Use with https://api.eaternity.org
3. Expired API Key
Problem: API key has been rotated or expired
Solution:
- Log into Forecast dashboard
- Navigate to Settings → API Keys
- Generate new API key
- Update your integration with new key
4. Missing Authorization Header
Problem: Forgetting to include authentication header
Solution:
# Wrong (no auth)
curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20"
# Correct (with auth)
curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20" \
-H "Authorization: Bearer your_api_key"
OAuth Token Issues
Symptoms:
- Token expired errors
- Invalid token responses
Solutions:
Implement Token Refresh
async function getValidToken() {
// Check if token exists and is still valid
if (accessToken && tokenExpiresAt > Date.now()) {
return accessToken;
}
// Refresh token
const response = await fetch('https://api.eaternity.org/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: clientId,
client_secret: clientSecret
})
});
const data = await response.json();
accessToken = data.access_token;
tokenExpiresAt = Date.now() + (data.expires_in * 1000);
return accessToken;
}
Data Submission Issues
Historical Data Import Failing
Symptoms:
- Import stuck in "processing" status
- Import fails with validation errors
- Some records skipped
Common Causes & Solutions:
1. Date Format Incorrect
Problem: Using wrong date format
Wrong Formats:
{
"date": "20-01-2024", // ❌ Wrong order
"date": "2024/01/20", // ❌ Slashes instead of hyphens
"date": "2024-1-20", // ❌ Not zero-padded
"date": "Jan 20, 2024" // ❌ Text format
}
Correct Format:
{
"date": "2024-01-20" // ✅ YYYY-MM-DD
}
2. Missing Required Fields
Problem: Omitting required data fields
Solution:
{
"kitchen_id": "your_kitchen_id", // ✅ Required
"date": "2024-01-20", // ✅ Required
"items": [ // ✅ Required
{
"item_id": "pasta_carbonara", // ✅ Required
"quantity_sold": 52, // ✅ Required
"name": "Pasta Carbonara", // ⚠️ Recommended
"price": 14.50, // ⚠️ Recommended
"category": "Main Course" // ⚠️ Recommended
}
]
}
3. Inconsistent Item IDs
Problem: Item IDs change between submissions
Wrong:
// Day 1
{"item_id": "pasta_carbonara", "quantity_sold": 52}
// Day 2
{"item_id": "Pasta_Carbonara", "quantity_sold": 48} // ❌ Different casing
// Day 3
{"item_id": "pasta-carbonara", "quantity_sold": 55} // ❌ Different format
Correct:
// All days use same ID
{"item_id": "pasta_carbonara", "quantity_sold": 52}
{"item_id": "pasta_carbonara", "quantity_sold": 48}
{"item_id": "pasta_carbonara", "quantity_sold": 55}
Fix Inconsistent Data:
# Request item ID mapping update
POST /v1/forecast/items/map
{
"kitchen_id": "your_kitchen_id",
"mappings": [
{
"variants": ["pasta_carbonara", "Pasta_Carbonara", "pasta-carbonara"],
"canonical_id": "pasta_carbonara"
}
]
}
4. Duplicate Data Submissions
Problem: Submitting same date multiple times
Solution:
# First submission (Day 1)
POST /v1/forecast/sales
{"date": "2024-01-20", "items": [...]}
# Later correction needed
# Use PATCH instead of POST
PATCH /v1/forecast/sales/2024-01-20
{"items": [{"item_id": "pasta_carbonara", "quantity_sold": 54}]}
5. Data Too Large
Problem: Exceeding request size limits
Solution:
# Wrong: All data in one request
bulk_import(sales_data_90_days) # May exceed limit
# Correct: Split into chunks
def chunk_data(data, chunk_size=30):
for i in range(0, len(data), chunk_size):
yield data[i:i + chunk_size]
for chunk in chunk_data(sales_data, chunk_size=30):
bulk_import(chunk)
time.sleep(1) # Avoid rate limits
Daily Sales Submission Failures
Symptoms:
- 422 Validation errors
- Sales data not appearing in dashboard
- Predictions not updating
Solutions:
Check Data Quality
Validation Endpoint:
POST /v1/forecast/sales/validate
{
"kitchen_id": "your_kitchen_id",
"date": "2024-01-20",
"items": [...]
}
# Response shows validation issues
{
"valid": false,
"errors": [
{
"field": "items[2].quantity_sold",
"value": -5,
"issue": "Quantity cannot be negative"
}
]
}
Common Validation Errors
| Error | Cause | Solution |
|---|---|---|
Quantity cannot be negative | Negative quantity value | Use 0 for items not sold |
Item ID contains invalid characters | Special characters in ID | Use only alphanumeric, underscore, hyphen |
Date in future | Date hasn't occurred yet | Only submit historical data |
Price exceeds maximum | Price > 999.99 | Contact support if legitimate |
Prediction Retrieval Issues
Predictions Not Available
Symptoms:
- 404 Not Found for prediction requests
- Empty predictions array
- "No predictions generated" message
Common Causes & Solutions:
1. Insufficient Training Data
Problem: Model hasn't finished training yet
Check Training Status:
GET /v1/forecast/training/status
# Response
{
"status": "training",
"progress": 45,
"expected_completion": "2024-01-25T10:00:00Z"
}
Solution: Wait for training to complete (typically 1-2 weeks)
2. No Recent Sales Data
Problem: Haven't submitted sales data recently
Check Last Data Submission:
GET /v1/forecast/sales/last
# Response
{
"last_submission": "2024-01-15",
"days_ago": 5,
"warning": "No data submitted in 5 days. Prediction accuracy may decline."
}
Solution: Submit missing sales data
3. Requesting Future Date Beyond Range
Problem: Requesting predictions too far in advance
Wrong:
# Today is 2024-01-20
GET /v1/forecast/predictions?date=2024-02-15 # 26 days ahead ❌
Correct:
# Maximum 14 days ahead
GET /v1/forecast/predictions?date=2024-02-03 # 14 days ahead ✅
4. Item Discontinued
Problem: Requesting predictions for removed menu item
Check Item Status:
GET /v1/forecast/items/pasta_carbonara
# Response
{
"item_id": "pasta_carbonara",
"status": "discontinued",
"last_sold": "2024-01-10",
"reason": "Zero sales for 10 consecutive days"
}
Solution: Reactivate item or remove from prediction requests
Prediction Accuracy Issues
Symptoms:
- Predictions consistently too high or too low
- Wide confidence intervals
- MAPE > 20%
Diagnostic Steps:
1. Check Data Quality Score
GET /v1/forecast/analytics/data-quality
# Response
{
"overall_score": 65, # ⚠️ Below 80%
"issues": [
{
"type": "missing_dates",
"severity": "high",
"details": "Missing sales data for 12 days in last 30 days"
},
{
"type": "inconsistent_naming",
"severity": "medium",
"details": "15 items with name variations"
}
],
"recommendations": [
"Submit missing sales data for: 2024-01-05, 2024-01-08, ..."
]
}
Solution: Address data quality issues identified
2. Verify Recent Changes
Problem: Menu changes, operational changes not reflected
Check Change Log:
GET /v1/forecast/changelog
# Response
{
"recent_changes": [
{
"date": "2024-01-15",
"type": "menu_change",
"details": "5 new items added, 3 items removed"
}
]
}
Solution:
- Wait 2-3 weeks after major menu changes
- Provide manual overrides during transition period
- Submit feedback on variance reasons
3. Identify Systematic Errors
Analyze Variance Patterns:
GET /v1/forecast/analytics/variance-analysis?days=30
# Response shows patterns
{
"patterns": [
{
"pattern": "consistently_over_predicting",
"items_affected": ["salad_items"],
"magnitude": "+15%",
"possible_cause": "Seasonal decline not yet learned"
}
]
}
Solution: Model learns over time, or provide external factor data (weather, events)
Network and Connectivity Issues
Timeout Errors
Symptoms:
- Request timeout after 30 seconds
- 504 Gateway Timeout errors
Solutions:
1. Increase Client Timeout
import requests
# Wrong: Default timeout too short
response = requests.get(url)
# Correct: Specify timeout
response = requests.get(url, timeout=60) # 60 seconds
2. Use Async for Bulk Operations
// Wrong: Sequential requests (slow)
for (const date of dates) {
await submitSales(date);
}
// Correct: Parallel requests (fast)
await Promise.all(dates.map(date => submitSales(date)));
Rate Limit Errors
Symptoms:
- 429 Too Many Requests
- "Rate limit exceeded" message
Solutions:
1. Respect Retry-After Header
import time
import requests
def make_request(url):
response = requests.get(url)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Waiting {retry_after} seconds...")
time.sleep(retry_after)
return make_request(url) # Retry
return response
2. Implement Request Queuing
from time import sleep
from collections import deque
class RateLimitedClient:
def __init__(self, requests_per_minute=100):
self.requests_per_minute = requests_per_minute
self.request_times = deque()
def make_request(self, url):
now = time.time()
# Remove requests older than 1 minute
while self.request_times and self.request_times[0] < now - 60:
self.request_times.popleft()
# Check if at limit
if len(self.request_times) >= self.requests_per_minute:
sleep_time = 60 - (now - self.request_times[0])
sleep(sleep_time)
# Make request
response = requests.get(url)
self.request_times.append(time.time())
return response
3. Request Rate Limit Increase
For high-volume integrations:
- Email forecast-api@eaternity.org
- Provide use case and expected request volume
- Custom rate limits available
Necta Integration Issues
Forecast Module Not Appearing
Symptoms:
- No "Forecast" tab in Necta Planning module
- Activation confirmed but interface unchanged
Solutions:
1. Clear Browser Cache
1. Close Necta completely
2. Clear browser cache:
- Chrome: Settings → Privacy → Clear browsing data
- Firefox: Options → Privacy → Clear Data
3. Restart browser
4. Log into Necta again
2. Verify Activation Status
Contact Necta support:
Subject: Forecast Module Activation Status
Account ID: [Your Necta Account ID]
Issue: Forecast module not visible after activation
Activation Date: [Date you were told it was activated]
3. Check User Permissions
Problem: User role doesn't have Forecast access
Solution:
- Admin must grant Forecast permissions
- Navigate to Necta Settings → Users → [Your User] → Permissions
- Enable "Forecast" module access
Data Not Syncing from Necta
Symptoms:
- Predictions not updating with latest Necta sales data
- Historical import incomplete
Solutions:
1. Verify Necta Data Entry
Check in Necta:
- Navigate to Sales → Daily Reports
- Verify sales data is entered for recent dates
- Ensure all menu items are recorded
2. Check Sync Status
Contact Eaternity support:
Subject: Necta Data Sync Issue
Kitchen ID: [Your Kitchen ID]
Necta Account ID: [Your Necta Account ID]
Last Successful Sync: [Check in Forecast dashboard]
Missing Dates: [List dates with no sync]
3. Reconnect Integration
Via Necta Dashboard:
- Navigate to Integrations → Eaternity Forecast
- Click "Disconnect"
- Click "Reconnect"
- Grant permissions again
Webhook Issues
Webhooks Not Delivered
Symptoms:
- No webhook notifications received
- Webhook endpoint never called
Solutions:
1. Verify Webhook Configuration
GET /v1/forecast/webhooks
# Check configuration
{
"webhooks": [
{
"webhook_id": "wh_123",
"url": "https://your-system.com/webhooks/forecast",
"events": ["predictions.generated"],
"status": "active",
"last_delivery": "2024-01-20T03:16:00Z"
}
]
}
If status: "failed": Check error logs
2. Check Endpoint Accessibility
Test from External Service:
# Use webhook.site or similar to test
curl -X POST "https://your-system.com/webhooks/forecast" \
-H "Content-Type: application/json" \
-d '{"test": "webhook"}'
Common Issues:
- Firewall blocking Forecast IPs
- HTTPS certificate invalid
- Endpoint returns non-2xx status code
Solution: Whitelist Forecast IPs (contact support for list)
3. Verify Signature Validation
Problem: Rejecting webhooks due to failed signature check
Debug Signature Validation:
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
# Compute expected signature
expected = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
# Debug output
print(f"Received signature: {signature}")
print(f"Expected signature: {expected}")
print(f"Match: {hmac.compare_digest(signature, expected)}")
return hmac.compare_digest(signature, expected)
Webhook Delivery Delays
Symptoms:
- Webhooks arrive late (>5 minutes after event)
- Inconsistent delivery times
Causes:
- Your endpoint slow to respond
- Network congestion
- Retry delays after failures
Solutions:
1. Optimize Endpoint Response Time
// Wrong: Slow processing blocks response
app.post('/webhooks/forecast', async (req, res) => {
await processWebhook(req.body); // Slow operation
res.status(200).send('OK');
});
// Correct: Acknowledge immediately, process async
app.post('/webhooks/forecast', async (req, res) => {
res.status(200).send('OK'); // Respond immediately
// Process asynchronously
processWebhookAsync(req.body).catch(err => {
console.error('Webhook processing error:', err);
});
});
2. Monitor Webhook Delivery
GET /v1/forecast/webhooks/wh_123/deliveries?limit=50
# Check recent deliveries
{
"deliveries": [
{
"delivery_id": "del_abc123",
"event": "predictions.generated",
"timestamp": "2024-01-20T03:15:42Z",
"response_code": 200,
"response_time_ms": 350,
"status": "success"
}
]
}
Performance Issues
Slow API Responses
Symptoms:
- Requests taking >5 seconds
- Inconsistent response times
Diagnostic Steps:
1. Identify Slow Endpoints
# Add timing to requests
time curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20" \
-H "Authorization: Bearer your_api_key"
2. Optimize Request Parameters
Slow (requesting all items):
GET /v1/forecast/predictions?date=2024-01-20&end_date=2024-01-27
# Returns 65 items × 7 days = 455 predictions
Fast (specific items only):
GET /v1/forecast/predictions?date=2024-01-20&items=pasta_carbonara,grilled_salmon
# Returns 2 items × 1 day = 2 predictions
3. Use Caching
import time
from functools import lru_cache
@lru_cache(maxsize=100)
def get_predictions_cached(date):
return get_predictions(date)
# Cache expires after 1 hour
def get_predictions_with_expiry(date):
cache_key = f"{date}_{int(time.time() // 3600)}"
return get_predictions_cached(cache_key)
Data Quality Issues
Low Data Quality Score
Symptoms:
- Data quality score less than 80%
- Warnings in dashboard
- Predictions with low confidence
Improvement Steps:
1. Run Data Quality Report
GET /v1/forecast/analytics/data-quality
# Detailed report
{
"overall_score": 72,
"components": {
"completeness": 85, # Missing some dates
"consistency": 65, # Naming issues
"accuracy": 80, # Some outliers
"timeliness": 70 # Delayed submissions
},
"issues": [...]
}
2. Fix Specific Issues
Missing Dates:
# Submit missing data
POST /v1/forecast/sales
{
"date": "2024-01-15",
"items": [...]
}
Inconsistent Naming:
# Standardize item names
POST /v1/forecast/items/standardize
{
"standardizations": [
{
"variants": ["pasta carbonara", "Pasta Carbonara", "PASTA_CARBONARA"],
"standard": "pasta_carbonara"
}
]
}
Outliers:
# Flag and explain outliers
POST /v1/forecast/sales/2024-01-15/annotate
{
"item_id": "grilled_salmon",
"note": "Holiday event, 2x normal volume expected",
"type": "special_event"
}
Getting Help
Support Channels
| Issue Type | Contact | Response Time |
|---|---|---|
| Critical (Production down) | forecast-api@eaternity.org + Phone | 4 hours |
| High (Integration broken) | forecast-api@eaternity.org | 24 hours |
| Medium (Accuracy questions) | forecast@eaternity.org | 48 hours |
| Low (General questions) | Documentation or email | 1 week |
Information to Include
In all support requests:
- Kitchen ID
- Integration type (Necta, Custom API, Manual)
- Description of issue
- Steps to reproduce
- Error messages (if any)
- Screenshots (if relevant)
- Example request/response (for API issues)
Self-Service Resources
- API Reference — Complete API documentation
- Integration Overview — All integration options
- Necta Integration — Necta-specific guide
- Custom API Integration — REST API guide
- Implementation Guide — Daily workflow best practices
See Also
- Integration Overview — All integration options
- Necta Integration — Necta-specific setup
- Custom API Integration — REST API guide
- API Reference — Complete API documentation