Integration de l'interface de programmation personnalisee
Ce guide fournit les details techniques pour integrer Eaternity Forecast a votre systeme de caisse, progiciel de gestion integre ou systeme de gestion de cuisine personnalise via notre interface de programmation REST.
Apercu de l'interface de programmation
URL de base
Production : https://api.eaternity.org/v1/forecast
Bac a sable : https://sandbox-api.eaternity.org/v1/forecast
Recommandation : Developpez et testez dans l'environnement bac a sable avant le deploiement en production.
Authentification
Methodes supportees :
- OAuth 2.0 (recommande pour les applications orientees utilisateur)
- Cles d'interface de programmation (recommande pour l'integration serveur a serveur)
Exigences de securite :
- Toutes les requetes doivent utiliser HTTPS
- TLS 1.2 ou superieur requis
- Les cles d'interface de programmation doivent etre stockees de maniere securisee (variables d'environnement, gestionnaires de secrets)
Voir la documentation de l'interface de programmation Eaternity →
Limites de debit
Limites standard :
- 100 requetes par minute
- 10 000 requetes par jour
- Allocation de rafale : 150 requetes en 60 secondes
Limites personnalisees :
- Disponibles pour les integrations a fort volume
- Contactez le support pour les demandes d'augmentation de limite
En-tetes de limite de debit :
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705752000
Demarrage rapide
1. Obtenir les identifiants de l'interface de programmation
Etape 1 : Contactez Eaternity pour l'acces a l'interface de programmation
- E-mail forecast@eaternity.org
- Fournissez les details de l'entreprise et le cas d'utilisation
Etape 2 : Recevez les identifiants de l'interface de programmation
- Cle d'interface de programmation pour l'authentification
- ID cuisine pour votre etablissement
- Acces a l'environnement bac a sable
Etape 3 : Testez l'authentification
curl -X GET "https://sandbox-api.eaternity.org/v1/forecast/ping" \
-H "Authorization: Bearer votre_cle_api_ici"
# Reponse de succes :
{
"status": "success",
"message": "Authentication successful",
"kitchen_id": "votre_id_cuisine"
}
2. Soumettre les donnees historiques
Point d'acces : POST /v1/forecast/sales/bulk
Exemple de requete :
curl -X POST "https://api.eaternity.org/v1/forecast/sales/bulk" \
-H "Authorization: Bearer votre_cle_api" \
-H "Content-Type: application/json" \
-d '{
"kitchen_id": "votre_id_cuisine",
"start_date": "2023-10-01",
"end_date": "2024-01-15",
"sales": [
{
"date": "2023-10-01",
"service_period": "lunch",
"items": [
{
"item_id": "pasta_carbonara",
"name": "Pasta Carbonara",
"quantity_sold": 52,
"price": 14.50,
"category": "Main Course"
},
{
"item_id": "caesar_salad",
"name": "Caesar Salad",
"quantity_sold": 31,
"price": 9.00,
"category": "Starter"
}
]
}
]
}'
Reponse :
{
"status": "success",
"message": "Historical data import queued",
"import_id": "imp_1234567890",
"total_records": 92,
"estimated_processing_time": "15 minutes",
"status_url": "/v1/forecast/imports/imp_1234567890/status"
}
3. Verifier le statut de l'import
Point d'acces : GET /v1/forecast/imports/{import_id}/status
curl -X GET "https://api.eaternity.org/v1/forecast/imports/imp_1234567890/status" \
-H "Authorization: Bearer votre_cle_api"
Reponse :
{
"import_id": "imp_1234567890",
"status": "processing",
"progress": 65,
"records_processed": 60,
"records_total": 92,
"records_failed": 0,
"errors": [],
"estimated_completion": "2024-01-20T10:35:00Z"
}
Valeurs de statut :
queued— En attente de traitementprocessing— Import en coursvalidating— Verification de la qualite des donneescompleted— Import reussifailed— L'import a rencontre des erreurs
4. Recuperer les previsions
Point d'acces : GET /v1/forecast/predictions
curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20" \
-H "Authorization: Bearer votre_cle_api"
Reponse :
{
"kitchen_id": "votre_id_cuisine",
"generated_at": "2024-01-20T03:15:42Z",
"predictions": [
{
"date": "2024-01-20",
"day_of_week": "Saturday",
"items": [
{
"item_id": "pasta_carbonara",
"name": "Pasta Carbonara",
"predicted_quantity": 52,
"confidence_interval": {
"lower": 48,
"upper": 56
},
"confidence_score": 0.92,
"accuracy_last_30_days": 94.2,
"factors": {
"day_of_week_effect": 1.05,
"weather_effect": 1.02,
"trend": "stable"
}
}
]
}
]
}
Points d'acces de l'interface de programmation
Points d'acces des donnees de ventes
Soumettre les ventes quotidiennes
POST /v1/forecast/sales
Soumettre les donnees de ventes pour une seule journee.
Corps de la requete :
{
"kitchen_id": "votre_id_cuisine",
"date": "2024-01-19",
"service_periods": [
{
"period": "lunch",
"items": [
{
"item_id": "pasta_carbonara",
"name": "Pasta Carbonara",
"quantity_sold": 52,
"price": 14.50,
"category": "Main Course"
}
]
},
{
"period": "dinner",
"items": [
{
"item_id": "grilled_salmon",
"name": "Grilled Salmon",
"quantity_sold": 38,
"price": 18.50,
"category": "Main Course"
}
]
}
]
}
Reponse :
{
"status": "success",
"date": "2024-01-19",
"items_processed": 12,
"next_prediction_update": "2024-01-20T03:00:00Z"
}
Codes de statut :
200— Succes400— Donnees de requete invalides401— Echec de l'authentification422— Echec de la validation des donnees429— Limite de debit depassee
Import historique en masse
POST /v1/forecast/sales/bulk
Importer de gros volumes de donnees historiques.
Corps de la requete :
{
"kitchen_id": "votre_id_cuisine",
"start_date": "2023-10-01",
"end_date": "2024-01-15",
"sales": [
{
"date": "2023-10-01",
"service_period": "lunch",
"items": [...]
}
]
}
Reponse :
{
"status": "success",
"import_id": "imp_1234567890",
"total_records": 92,
"status_url": "/v1/forecast/imports/imp_1234567890/status"
}
Meilleures pratiques :
- Maximum 365 jours par import en masse
- Maximum 10 000 enregistrements par requete
- Pour les ensembles de donnees plus volumineux, divisez en plusieurs requetes
- Surveillez le statut de l'import via le point d'acces de statut
Mettre a jour les donnees de ventes
PATCH /v1/forecast/sales/{date}
Corriger les donnees de ventes precedemment soumises.
Corps de la requete :
{
"kitchen_id": "votre_id_cuisine",
"items": [
{
"item_id": "pasta_carbonara",
"quantity_sold": 54
}
]
}
Cas d'utilisation :
- Corriger les erreurs de saisie
- Mettre a jour avec les comptages finaux de fin de journee
- Ajouter des periodes de service manquantes
Points d'acces des previsions
Obtenir les previsions pour une plage de dates
GET /v1/forecast/predictions
Parametres de requete :
date(obligatoire) — Date ou date de debut (AAAA-MM-JJ)end_date(optionnel) — Date de fin pour la plage (AAAA-MM-JJ)items(optionnel) — IDs d'articles separes par des virgules pour filtrer
Exemples :
# Date unique
GET /v1/forecast/predictions?date=2024-01-20
# Plage de dates (7 prochains jours)
GET /v1/forecast/predictions?date=2024-01-20&end_date=2024-01-27
# Articles specifiques uniquement
GET /v1/forecast/predictions?date=2024-01-20&items=pasta_carbonara,grilled_salmon
Reponse :
{
"kitchen_id": "votre_id_cuisine",
"generated_at": "2024-01-20T03:15:42Z",
"predictions": [
{
"date": "2024-01-20",
"day_of_week": "Saturday",
"items": [...]
},
{
"date": "2024-01-21",
"day_of_week": "Sunday",
"items": [...]
}
]
}
Obtenir la prevision pour un article unique
GET /v1/forecast/predictions/{item_id}
Parametres de requete :
date(obligatoire) — Date de previsiondays_ahead(optionnel) — Nombre de jours a prevoir (par defaut : 7, max : 14)
Exemple :
GET /v1/forecast/predictions/pasta_carbonara?date=2024-01-20&days_ahead=7
Reponse :
{
"item_id": "pasta_carbonara",
"name": "Pasta Carbonara",
"predictions": [
{
"date": "2024-01-20",
"predicted_quantity": 52,
"confidence_interval": {
"lower": 48,
"upper": 56
},
"confidence_score": 0.92
}
],
"historical_accuracy": {
"last_7_days": 95.2,
"last_30_days": 94.2,
"all_time": 93.8
}
}
Modifier une prevision
POST /v1/forecast/predictions/override
Modifier manuellement une prevision pour des circonstances specifiques.
Corps de la requete :
{
"kitchen_id": "votre_id_cuisine",
"date": "2024-01-25",
"item_id": "pasta_carbonara",
"override_quantity": 75,
"reason": "Conference group booking (50 pax confirmed)",
"preserve_ratios": true
}
Parametres :
override_quantity(obligatoire) — Nouvelle quantite prevuereason(obligatoire) — Explication de la modification (utilisee pour l'apprentissage)preserve_ratios(optionnel) — Ajuster les articles associes proportionnellement
Reponse :
{
"status": "success",
"original_prediction": 52,
"override_quantity": 75,
"affected_items": [
{
"item_id": "caesar_salad",
"original": 31,
"adjusted": 45
}
]
}
Points d'acces analytiques
Obtenir le rapport de precision
GET /v1/forecast/analytics/accuracy
Parametres de requete :
start_date(obligatoire) — Date de debut du rapportend_date(obligatoire) — Date de fin du rapportgroup_by(optionnel) —day,week,month, ouitem
Exemple :
GET /v1/forecast/analytics/accuracy?start_date=2024-01-01&end_date=2024-01-31&group_by=week
Reponse :
{
"period": {
"start": "2024-01-01",
"end": "2024-01-31"
},
"overall_mape": 12.3,
"by_week": [
{
"week": 1,
"start_date": "2024-01-01",
"mape": 13.5,
"items_within_10_percent": 52,
"total_items": 65
}
],
"top_performers": [
{
"item_id": "pasta_carbonara",
"mape": 8.2
}
],
"needs_attention": [
{
"item_id": "daily_special",
"mape": 22.1,
"reason": "High variance, new items frequently"
}
]
}
Obtenir le rapport de reduction du gaspillage
GET /v1/forecast/analytics/waste-reduction
Suivre les economies de gaspillage alimentaire depuis l'utilisation de Forecast.
Parametres de requete :
baseline_start(obligatoire) — Debut de la periode de reference (avant Forecast)baseline_end(obligatoire) — Fin de la periode de referencecomparison_start(obligatoire) — Debut de la periode d'utilisation de Forecastcomparison_end(obligatoire) — Fin de la periode d'utilisation de Forecast
Reponse :
{
"baseline": {
"period": "2023-10-01 to 2023-12-31",
"waste_rate": 12.8,
"total_waste_portions": 3845,
"estimated_cost": 21148.50
},
"comparison": {
"period": "2024-01-01 to 2024-03-31",
"waste_rate": 7.2,
"total_waste_portions": 2156,
"estimated_cost": 11858.00
},
"improvement": {
"waste_rate_reduction": 43.8,
"portions_saved": 1689,
"cost_savings": 9290.50,
"annualized_savings": 11748.60
}
}
Webhooks
Apercu
Les webhooks permettent a Forecast d'envoyer des notifications a votre systeme au lieu de necessiter un polling.
Cas d'utilisation :
- Recevoir des notifications quand de nouvelles previsions sont pretes
- Obtenir des alertes pour les grandes variances entre prevision et reel
- Surveiller les problemes de qualite des donnees
- Suivre les evenements de re-entrainement du modele
Configuration
Configurer le point d'acces webhook :
POST /v1/forecast/webhooks
{
"kitchen_id": "votre_id_cuisine",
"url": "https://votre-systeme.com/webhooks/forecast",
"events": [
"predictions.generated",
"variance.large",
"data.quality_issue",
"model.retrained"
],
"secret": "votre_secret_webhook_pour_validation_signature"
}
Reponse :
{
"webhook_id": "wh_1234567890",
"status": "active",
"events": ["predictions.generated", "variance.large"],
"created_at": "2024-01-20T10:00:00Z"
}
Evenements webhook
predictions.generated
Declenche quand de nouvelles previsions sont generees (quotidiennement a 3h00).
Payload :
{
"event": "predictions.generated",
"timestamp": "2024-01-20T03:15:42Z",
"kitchen_id": "votre_id_cuisine",
"data": {
"date_range": {
"start": "2024-01-20",
"end": "2024-01-27"
},
"total_items": 65,
"prediction_url": "/v1/forecast/predictions?date=2024-01-20"
}
}
variance.large
Declenche quand les ventes reelles different significativement de la prevision (plus de 20 % par defaut).
Payload :
{
"event": "variance.large",
"timestamp": "2024-01-19T21:30:00Z",
"kitchen_id": "votre_id_cuisine",
"data": {
"date": "2024-01-19",
"item_id": "grilled_salmon",
"predicted": 28,
"actual": 42,
"variance_percent": 50.0,
"possible_causes": ["weather_warmer_than_forecast", "event_nearby"]
}
}
data.quality_issue
Declenche quand des problemes de qualite des donnees sont detectes.
Payload :
{
"event": "data.quality_issue",
"timestamp": "2024-01-20T04:00:00Z",
"kitchen_id": "votre_id_cuisine",
"data": {
"issue_type": "missing_data",
"severity": "warning",
"description": "No sales data received for 2024-01-19",
"recommendation": "Submit sales data for 2024-01-19 to maintain prediction accuracy"
}
}
model.retrained
Declenche quand le modele est re-entraine avec de nouvelles donnees (hebdomadairement).
Payload :
{
"event": "model.retrained",
"timestamp": "2024-01-20T04:30:00Z",
"kitchen_id": "votre_id_cuisine",
"data": {
"training_data_range": {
"start": "2023-10-01",
"end": "2024-01-19"
},
"accuracy_improvement": 1.2,
"new_mape": 12.1,
"previous_mape": 13.3
}
}
Securite des webhooks
Validation de signature :
Toutes les requetes webhook incluent l'en-tete X-Forecast-Signature pour verification.
Exemple de verification (Python) :
import hmac
import hashlib
def verify_webhook_signature(payload, signature, secret):
expected_signature = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_signature)
# Dans votre gestionnaire de webhook :
payload = request.body
signature = request.headers['X-Forecast-Signature']
secret = 'votre_secret_webhook'
if verify_webhook_signature(payload, signature, secret):
# Traiter le webhook
pass
else:
# Rejeter la requete (probleme de securite potentiel)
return 401
Formats de donnees et validation
Exigences d'ID d'article
Format :
- Caracteres alphanumeriques, underscores, tirets uniquement
- Maximum 100 caracteres
- Sensible a la casse
- Doit etre coherent sur toutes les requetes
Bons exemples :
pasta_carbonaragrilled-salmon-lemonITEM_12345
Mauvais exemples :
Pasta Carbonara(contient des espaces)item#12345(contient un caractere special)- Casse differente :
Pasta_Carbonaravspasta_carbonara(incoherent)
Format de date
Format requis : AAAA-MM-JJ (ISO 8601)
Valide :
2024-01-202024-12-31
Invalide :
20-01-2024(mauvais ordre)2024/01/20(barres obliques au lieu de tirets)2024-1-20(pas de zero initial)
Validation des quantites
Exigences :
- Valeurs entieres uniquement
- Minimum : 0
- Maximum : 10 000 (contactez le support pour des limites superieures)
- Valeurs negatives rejetees
Validation des prix
Exigences :
- Valeurs decimales (2 decimales)
- Minimum : 0,00
- Maximum : 999,99
- Devise non specifiee (utilisez une devise coherente sur toutes les donnees)
Gestion des erreurs
Format de reponse d'erreur
{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid date format",
"details": {
"field": "date",
"value": "20-01-2024",
"expected": "YYYY-MM-DD"
}
}
}
Codes d'erreur courants
| Code | Statut HTTP | Description | Solution |
|---|---|---|---|
AUTHENTICATION_FAILED | 401 | Cle d'interface de programmation invalide | Verifiez que la cle est correcte |
RATE_LIMIT_EXCEEDED | 429 | Trop de requetes | Attendez et reessayez, ou demandez une augmentation de limite |
VALIDATION_ERROR | 422 | Format de donnees invalide | Verifiez le format de la requete contre la documentation |
NOT_FOUND | 404 | Ressource non trouvee | Verifiez kitchen_id ou item_id |
INTERNAL_ERROR | 500 | Erreur serveur | Reessayez avec backoff exponentiel |
Logique de reessai
Strategie de reessai recommandee :
import time
import requests
def make_request_with_retry(url, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.get(url)
if response.status_code == 200:
return response.json()
elif response.status_code == 429:
# Limite de debit - attendre et reessayer
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after)
elif response.status_code >= 500:
# Erreur serveur - backoff exponentiel
wait_time = 2 ** attempt
time.sleep(wait_time)
else:
# Erreur client - ne pas reessayer
raise Exception(f"Error {response.status_code}: {response.text}")
except requests.exceptions.RequestException as e:
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt)
raise Exception("Max retries exceeded")
SDK et bibliotheques client
SDK officiels
SDK Python (Recommande) :
pip install eaternity-forecast
Utilisation :
from eaternity_forecast import ForecastClient
client = ForecastClient(api_key='votre_cle_api')
# Soumettre les ventes quotidiennes
client.sales.submit(
date='2024-01-19',
items=[
{'item_id': 'pasta_carbonara', 'quantity_sold': 52}
]
)
# Obtenir les previsions
predictions = client.predictions.get(date='2024-01-20')
SDK JavaScript/TypeScript :
npm install @eaternity/forecast-sdk
Utilisation :
import { ForecastClient } from '@eaternity/forecast-sdk';
const client = new ForecastClient({ apiKey: 'votre_cle_api' });
// Obtenir les previsions
const predictions = await client.predictions.get({ date: '2024-01-20' });
SDK communautaires :
- Ruby :
gem install eaternity-forecast - PHP :
composer require eaternity/forecast-sdk - Go :
go get github.com/eaternity/forecast-go
Tests
Environnement bac a sable
Objectif : Tester l'integration sans affecter les donnees de production
URL de base : https://sandbox-api.eaternity.org/v1/forecast
Fonctionnalites :
- Identifiants d'authentification separes
- Les donnees de test peuvent etre reinitialisees
- Meme interface de programmation qu'en production
- Generation de previsions plus rapide (pour les tests)
Limitations :
- Les previsions peuvent etre moins precises (utilisant des donnees synthetiques)
- Pas de garantie de niveau de service
- Donnees reinitialisees hebdomadairement
Exemple de test d'integration
import unittest
from eaternity_forecast import ForecastClient
class TestForecastIntegration(unittest.TestCase):
def setUp(self):
self.client = ForecastClient(
api_key='sandbox_api_key',
base_url='https://sandbox-api.eaternity.org/v1/forecast'
)
def test_submit_sales_and_get_predictions(self):
# Soumettre les donnees historiques
response = self.client.sales.submit(
date='2024-01-19',
items=[
{'item_id': 'test_item_1', 'quantity_sold': 50},
{'item_id': 'test_item_2', 'quantity_sold': 30}
]
)
self.assertEqual(response['status'], 'success')
# Attendre le traitement (le bac a sable est plus rapide)
time.sleep(10)
# Obtenir les previsions
predictions = self.client.predictions.get(date='2024-01-20')
self.assertIsNotNone(predictions)
self.assertGreater(len(predictions['predictions']), 0)
Liste de verification du deploiement en production
Avant le lancement
- Teste tous les points d'acces dans l'environnement bac a sable
- Implemente la gestion des erreurs et la logique de reessai
- Configure les points d'acces webhook (si utilises)
- Verifie la validation de signature webhook
- Mis en place la surveillance et la journalisation
- Documente l'integration pour l'equipe
- Obtenu les identifiants d'interface de programmation de production
- Importe les donnees historiques avec succes
- Verifie la note de qualite des donnees superieure a 80 %
- Complete l'entrainement du modele
Mise en production
- Bascule des URLs bac a sable vers production
- Mis a jour les identifiants d'interface de programmation vers production
- Surveille les premieres 24 heures de previsions
- Verifie la soumission quotidienne des ventes fonctionnelle
- Confirme la recuperation des previsions fonctionnelle
- Verifie la livraison des webhooks (si configure)
Apres le lancement
- Suit les metriques de precision hebdomadairement
- Examine et repond aux alertes de grandes variances
- Fournit des retours sur la qualite des previsions
- Optimise les flux de preparation bases sur la confiance
- Planifie des revues de performance mensuelles
Support
Support technique
E-mail : forecast-api@eaternity.org
Delais de reponse :
- Critique (production hors service) : 4 heures
- Eleve (performance degradee) : 24 heures
- Moyen (questions, bogues) : 48 heures
- Faible (ameliorations) : 1 semaine
Inclure dans les demandes de support :
- ID cuisine
- Point d'acces et methode de l'interface de programmation
- Exemples de requete/reponse
- Messages d'erreur
- Horodatage du probleme
Documentation
- Reference de l'interface de programmation — Documentation complete des points d'acces
- Apercu des integrations — Toutes les options d'integration
- Depannage — Problemes courants
Voir aussi
- Apercu des integrations — Comparer les methodes d'integration
- Integration Necta — Guide specifique Necta
- Depannage — Problemes courants
- Reference de l'interface de programmation — Documentation complete de l'interface de programmation