Saltar al contenido principal

Integración de interfaz de programación de aplicaciones personalizada

Esta guía proporciona detalles técnicos para integrar Eaternity Forecast con vuestro sistema personalizado de punto de venta, planificación de recursos empresariales o gestión de cocina mediante nuestra interfaz de programación de aplicaciones REST.

Visión general de la interfaz de programación de aplicaciones

URL base

Producción: https://api.eaternity.org/v1/forecast
Pruebas: https://sandbox-api.eaternity.org/v1/forecast

Recomendación: Desarrollad y probad en el entorno de pruebas antes del despliegue en producción.

Autenticación

Métodos soportados:

  1. OAuth 2.0 (recomendado para aplicaciones orientadas al usuario)
  2. Claves de interfaz de programación de aplicaciones (recomendado para integración servidor a servidor)

Requisitos de seguridad:

  • Todas las solicitudes deben usar HTTPS
  • TLS 1.2 o superior requerido
  • Las claves de interfaz de programación de aplicaciones deben almacenarse de forma segura (variables de entorno, gestores de secretos)

Ved la documentación de la interfaz de programación de aplicaciones de Eaternity →

Límites de tasa

Límites estándar:

  • 100 solicitudes por minuto
  • 10.000 solicitudes por día
  • Tolerancia de ráfaga: 150 solicitudes en 60 segundos

Límites personalizados:

  • Disponibles para integraciones de alto volumen
  • Contactad con soporte para solicitudes de aumento de límite de tasa

Cabeceras de límite de tasa:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705752000

Inicio rápido

1. Obtener credenciales de interfaz de programación de aplicaciones

Paso 1: Contactad con Eaternity para acceso a la interfaz de programación de aplicaciones

Paso 2: Recibid credenciales de interfaz de programación de aplicaciones

  • Clave de interfaz de programación de aplicaciones para autenticación
  • ID de cocina para vuestra ubicación
  • Acceso al entorno de pruebas

Paso 3: Probad la autenticación

curl -X GET "https://sandbox-api.eaternity.org/v1/forecast/ping" \
-H "Authorization: Bearer your_api_key_here"

# Respuesta exitosa:
{
"status": "success",
"message": "Authentication successful",
"kitchen_id": "your_kitchen_id"
}

2. Enviar datos históricos

Punto final: POST /v1/forecast/sales/bulk

Ejemplo de solicitud:

curl -X POST "https://api.eaternity.org/v1/forecast/sales/bulk" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"kitchen_id": "your_kitchen_id",
"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"
}
]
}
]
}'

Respuesta:

{
"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. Comprobar estado de importación

Punto final: GET /v1/forecast/imports/{import_id}/status

curl -X GET "https://api.eaternity.org/v1/forecast/imports/imp_1234567890/status" \
-H "Authorization: Bearer your_api_key"

Respuesta:

{
"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"
}

Valores de estado:

  • queued — Esperando para procesar
  • processing — Importando actualmente
  • validating — Comprobando calidad de datos
  • completed — Importación exitosa
  • failed — La importación encontró errores

4. Recuperar predicciones

Punto final: GET /v1/forecast/predictions

curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20" \
-H "Authorization: Bearer your_api_key"

Respuesta:

{
"kitchen_id": "your_kitchen_id",
"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"
}
}
]
}
]
}

Puntos finales de la interfaz de programación de aplicaciones

Puntos finales de datos de ventas

Enviar ventas diarias

POST /v1/forecast/sales

Enviar datos de ventas de un solo día.

Cuerpo de solicitud:

{
"kitchen_id": "your_kitchen_id",
"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"
}
]
}
]
}

Respuesta:

{
"status": "success",
"date": "2024-01-19",
"items_processed": 12,
"next_prediction_update": "2024-01-20T03:00:00Z"
}

Códigos de estado:

  • 200 — Éxito
  • 400 — Datos de solicitud inválidos
  • 401 — Autenticación fallida
  • 422 — Validación de datos fallida
  • 429 — Límite de tasa excedido

Importación histórica masiva

POST /v1/forecast/sales/bulk

Importar grandes volúmenes de datos históricos.

Cuerpo de solicitud:

{
"kitchen_id": "your_kitchen_id",
"start_date": "2023-10-01",
"end_date": "2024-01-15",
"sales": [
{
"date": "2023-10-01",
"service_period": "lunch",
"items": [...]
}
]
}

Respuesta:

{
"status": "success",
"import_id": "imp_1234567890",
"total_records": 92,
"status_url": "/v1/forecast/imports/imp_1234567890/status"
}

Mejores prácticas:

  • Máximo 365 días por importación masiva
  • Máximo 10.000 registros por solicitud
  • Para conjuntos de datos más grandes, dividir en múltiples solicitudes
  • Monitorizar el estado de importación vía el punto final de estado

Actualizar datos de ventas

PATCH /v1/forecast/sales/{date}

Corregir datos de ventas enviados previamente.

Cuerpo de solicitud:

{
"kitchen_id": "your_kitchen_id",
"items": [
{
"item_id": "pasta_carbonara",
"quantity_sold": 54
}
]
}

Casos de uso:

  • Corregir errores de entrada de datos
  • Actualizar con recuentos finales de fin de día
  • Añadir períodos de servicio faltantes

Puntos finales de predicciones

Obtener predicciones para rango de fechas

GET /v1/forecast/predictions

Parámetros de consulta:

  • date (requerido) — Fecha o fecha de inicio (AAAA-MM-DD)
  • end_date (opcional) — Fecha de fin para rango (AAAA-MM-DD)
  • items (opcional) — IDs de artículos separados por comas para filtrar

Ejemplos:

# Fecha única
GET /v1/forecast/predictions?date=2024-01-20

# Rango de fechas (próximos 7 días)
GET /v1/forecast/predictions?date=2024-01-20&end_date=2024-01-27

# Solo artículos específicos
GET /v1/forecast/predictions?date=2024-01-20&items=pasta_carbonara,grilled_salmon

Respuesta:

{
"kitchen_id": "your_kitchen_id",
"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": [...]
}
]
}

Obtener predicción para un solo artículo

GET /v1/forecast/predictions/{item_id}

Parámetros de consulta:

  • date (requerido) — Fecha de predicción
  • days_ahead (opcional) — Número de días a pronosticar (por defecto: 7, máximo: 14)

Ejemplo:

GET /v1/forecast/predictions/pasta_carbonara?date=2024-01-20&days_ahead=7

Respuesta:

{
"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
}
}

Anular predicción

POST /v1/forecast/predictions/override

Anular manualmente una predicción para circunstancias específicas.

Cuerpo de solicitud:

{
"kitchen_id": "your_kitchen_id",
"date": "2024-01-25",
"item_id": "pasta_carbonara",
"override_quantity": 75,
"reason": "Conference group booking (50 pax confirmed)",
"preserve_ratios": true
}

Parámetros:

  • override_quantity (requerido) — Nueva cantidad predicha
  • reason (requerido) — Explicación para la anulación (usado para aprendizaje)
  • preserve_ratios (opcional) — Ajustar artículos relacionados proporcionalmente

Respuesta:

{
"status": "success",
"original_prediction": 52,
"override_quantity": 75,
"affected_items": [
{
"item_id": "caesar_salad",
"original": 31,
"adjusted": 45
}
]
}

Puntos finales de análisis

Obtener informe de precisión

GET /v1/forecast/analytics/accuracy

Parámetros de consulta:

  • start_date (requerido) — Fecha de inicio del informe
  • end_date (requerido) — Fecha de fin del informe
  • group_by (opcional) — day, week, month o item

Ejemplo:

GET /v1/forecast/analytics/accuracy?start_date=2024-01-01&end_date=2024-01-31&group_by=week

Respuesta:

{
"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"
}
]
}

Obtener informe de reducción de desperdicios

GET /v1/forecast/analytics/waste-reduction

Rastrear ahorro de desperdicio de alimentos desde el uso de Forecast.

Parámetros de consulta:

  • baseline_start (requerido) — Inicio del período de referencia (pre-Forecast)
  • baseline_end (requerido) — Fin del período de referencia
  • comparison_start (requerido) — Inicio del período de uso de Forecast
  • comparison_end (requerido) — Fin del período de uso de Forecast

Respuesta:

{
"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
}
}

Ganchos web

Visión general

Los ganchos web permiten a Forecast enviar notificaciones a vuestro sistema en lugar de requerir sondeo.

Casos de uso:

  • Recibir notificaciones cuando hay nuevas predicciones listas
  • Recibir alertas de gran varianza entre predicción y real
  • Monitorizar problemas de calidad de datos
  • Rastrear eventos de reentrenamiento del modelo

Configuración

Configurar punto final de gancho web:

POST /v1/forecast/webhooks

{
"kitchen_id": "your_kitchen_id",
"url": "https://your-system.com/webhooks/forecast",
"events": [
"predictions.generated",
"variance.large",
"data.quality_issue",
"model.retrained"
],
"secret": "your_webhook_secret_for_signature_validation"
}

Respuesta:

{
"webhook_id": "wh_1234567890",
"status": "active",
"events": ["predictions.generated", "variance.large"],
"created_at": "2024-01-20T10:00:00Z"
}

Eventos de ganchos web

predictions.generated

Se activa cuando se generan nuevas predicciones (diariamente a las 3:00 AM).

Carga útil:

{
"event": "predictions.generated",
"timestamp": "2024-01-20T03:15:42Z",
"kitchen_id": "your_kitchen_id",
"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

Se activa cuando las ventas reales difieren significativamente de la predicción (más del 20% por defecto).

Carga útil:

{
"event": "variance.large",
"timestamp": "2024-01-19T21:30:00Z",
"kitchen_id": "your_kitchen_id",
"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

Se activa cuando se detectan problemas de calidad de datos.

Carga útil:

{
"event": "data.quality_issue",
"timestamp": "2024-01-20T04:00:00Z",
"kitchen_id": "your_kitchen_id",
"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

Se activa cuando el modelo se reentrena con nuevos datos (semanalmente).

Carga útil:

{
"event": "model.retrained",
"timestamp": "2024-01-20T04:30:00Z",
"kitchen_id": "your_kitchen_id",
"data": {
"training_data_range": {
"start": "2023-10-01",
"end": "2024-01-19"
},
"accuracy_improvement": 1.2,
"new_mape": 12.1,
"previous_mape": 13.3
}
}

Seguridad de ganchos web

Validación de firma:

Todas las solicitudes de ganchos web incluyen la cabecera X-Forecast-Signature para verificación.

Ejemplo de verificación (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)

# En vuestro manejador de gancho web:
payload = request.body
signature = request.headers['X-Forecast-Signature']
secret = 'your_webhook_secret'

if verify_webhook_signature(payload, signature, secret):
# Procesar gancho web
pass
else:
# Rechazar solicitud (posible problema de seguridad)
return 401

Formatos de datos y validación

Requisitos de ID de artículo

Formato:

  • Solo caracteres alfanuméricos, guiones bajos, guiones
  • Máximo 100 caracteres
  • Sensible a mayúsculas y minúsculas
  • Debe ser consistente en todas las solicitudes

Buenos ejemplos:

  • pasta_carbonara
  • grilled-salmon-lemon
  • ITEM_12345

Malos ejemplos:

  • Pasta Carbonara (contiene espacios)
  • item#12345 (contiene carácter especial)
  • Diferente uso de mayúsculas: Pasta_Carbonara vs pasta_carbonara (inconsistente)

Formato de fecha

Formato requerido: AAAA-MM-DD (ISO 8601)

Válido:

  • 2024-01-20
  • 2024-12-31

Inválido:

  • 20-01-2024 (orden incorrecto)
  • 2024/01/20 (barras en lugar de guiones)
  • 2024-1-20 (sin ceros iniciales)

Validación de cantidad

Requisitos:

  • Solo valores enteros
  • Mínimo: 0
  • Máximo: 10.000 (contactad con soporte para límites más altos)
  • Valores negativos rechazados

Validación de precio

Requisitos:

  • Valores decimales (2 decimales)
  • Mínimo: 0,00
  • Máximo: 999,99
  • Moneda no especificada (usad moneda consistente en todos los datos)

Manejo de errores

Formato de respuesta de error

{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid date format",
"details": {
"field": "date",
"value": "20-01-2024",
"expected": "YYYY-MM-DD"
}
}
}

Códigos de error comunes

CódigoEstado HTTPDescripciónSolución
AUTHENTICATION_FAILED401Clave de interfaz de programación de aplicaciones inválidaVerificar que la clave de interfaz de programación de aplicaciones es correcta
RATE_LIMIT_EXCEEDED429Demasiadas solicitudesEsperar y reintentar, o solicitar aumento de límite
VALIDATION_ERROR422Formato de datos inválidoComprobar formato de solicitud contra la documentación
NOT_FOUND404Recurso no encontradoVerificar kitchen_id o item_id
INTERNAL_ERROR500Error del servidorReintentar con retroceso exponencial

Lógica de reintento

Estrategia de reintento recomendada:

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:
# Límite de tasa - esperar y reintentar
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after)
elif response.status_code >= 500:
# Error del servidor - retroceso exponencial
wait_time = 2 ** attempt
time.sleep(wait_time)
else:
# Error del cliente - no reintentar
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 y bibliotecas cliente

SDKs oficiales

SDK de Python (Recomendado):

pip install eaternity-forecast

Uso:

from eaternity_forecast import ForecastClient

client = ForecastClient(api_key='your_api_key')

# Enviar ventas diarias
client.sales.submit(
date='2024-01-19',
items=[
{'item_id': 'pasta_carbonara', 'quantity_sold': 52}
]
)

# Obtener predicciones
predictions = client.predictions.get(date='2024-01-20')

SDK de JavaScript/TypeScript:

npm install @eaternity/forecast-sdk

Uso:

import { ForecastClient } from '@eaternity/forecast-sdk';

const client = new ForecastClient({ apiKey: 'your_api_key' });

// Obtener predicciones
const predictions = await client.predictions.get({ date: '2024-01-20' });

SDKs de la comunidad:

  • Ruby: gem install eaternity-forecast
  • PHP: composer require eaternity/forecast-sdk
  • Go: go get github.com/eaternity/forecast-go

Ver documentación de SDK →

Pruebas

Entorno de pruebas

Propósito: Probar la integración sin afectar datos de producción

URL base: https://sandbox-api.eaternity.org/v1/forecast

Funcionalidades:

  • Credenciales de autenticación separadas
  • Los datos de prueba pueden reiniciarse
  • Misma interfaz de programación de aplicaciones que producción
  • Generación de predicciones más rápida (para pruebas)

Limitaciones:

  • Las predicciones pueden ser menos precisas (usando datos sintéticos)
  • Sin garantías de acuerdo de nivel de servicio
  • Datos reiniciados semanalmente

Ejemplo de prueba de integración

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):
# Enviar datos históricos
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')

# Esperar procesamiento (el entorno de pruebas es más rápido)
time.sleep(10)

# Obtener predicciones
predictions = self.client.predictions.get(date='2024-01-20')
self.assertIsNotNone(predictions)
self.assertGreater(len(predictions['predictions']), 0)

Lista de verificación de despliegue en producción

Pre-lanzamiento

  • Probados todos los puntos finales en entorno de pruebas
  • Implementado manejo de errores y lógica de reintento
  • Configurados puntos finales de ganchos web (si se usan)
  • Verificada validación de firma de ganchos web
  • Configurada monitorización y registro
  • Integración documentada para el equipo
  • Obtenidas credenciales de interfaz de programación de aplicaciones de producción
  • Datos históricos importados con éxito
  • Verificada puntuación de calidad de datos superior al 80%
  • Entrenamiento del modelo completado

Puesta en marcha

  • Cambiado de URLs de pruebas a producción
  • Actualizadas credenciales de interfaz de programación de aplicaciones a producción
  • Monitorizadas primeras 24 horas de predicciones
  • Verificado envío diario de ventas funcionando
  • Confirmada recuperación de predicciones funcionando
  • Comprobada entrega de ganchos web (si está configurado)

Post-lanzamiento

  • Rastrear métricas de precisión semanalmente
  • Revisar y responder a alertas de grandes varianzas
  • Proporcionar comentarios sobre calidad de predicción
  • Optimizar flujos de trabajo de preparación basándose en confianza
  • Programar revisiones mensuales de rendimiento

Soporte

Soporte técnico

Correo electrónico: forecast-api@eaternity.org

Tiempos de respuesta:

  • Crítico (producción caída): 4 horas
  • Alto (rendimiento degradado): 24 horas
  • Medio (preguntas, errores): 48 horas
  • Bajo (mejoras): 1 semana

Incluir en solicitudes de soporte:

  • ID de cocina
  • Punto final y método de la interfaz de programación de aplicaciones
  • Ejemplos de solicitud/respuesta
  • Mensajes de error
  • Marca de tiempo del problema

Documentación

Ved también