Skip to main content

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:

  1. Log into Forecast dashboard
  2. Navigate to Settings → API Keys
  3. Generate new API key
  4. 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

ErrorCauseSolution
Quantity cannot be negativeNegative quantity valueUse 0 for items not sold
Item ID contains invalid charactersSpecial characters in IDUse only alphanumeric, underscore, hyphen
Date in futureDate hasn't occurred yetOnly submit historical data
Price exceeds maximumPrice > 999.99Contact 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:

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:

  1. Navigate to Integrations → Eaternity Forecast
  2. Click "Disconnect"
  3. Click "Reconnect"
  4. 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 TypeContactResponse Time
Critical (Production down)forecast-api@eaternity.org + Phone4 hours
High (Integration broken)forecast-api@eaternity.org24 hours
Medium (Accuracy questions)forecast@eaternity.org48 hours
Low (General questions)Documentation or email1 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

See Also