EmiliaVision Webhook Integration - Quick Start Guide¶
Time to First Webhook: 15 minutes
Time to Production: 2-3 days
🎯 Goal¶
Get your first webhook sent to EmiliaVision in 15 minutes, then gradually enhance the integration.
📋 Prerequisites¶
Before starting, ensure you have: - [ ] Your webhook token from EmiliaVision (request at team@emiliavision.com) - [ ] Access to your POS system's integration capabilities - [ ] Ability to send HTTP POST requests (any programming language)
🚀 Step 1: Send Your First Test Webhook (5 minutes)¶
Using cURL (Command Line)¶
# Replace YOUR_TOKEN with your actual token
curl -X POST \
"https://api.emiliavision.com/webhooks/v1/pos/YOUR_TOKEN?env=dev" \
-H "Content-Type: application/json" \
-d '{
"event": "test",
"table_number": "Mesa 1",
"timestamp": "2025-11-24T12:00:00-03:00"
}'
Expected Response:
{
"status": "success",
"event_id": "019ab6ed-150a-7be1-920f-ab82305e5d41",
"message": "Webhook received and stored",
"received_at": "2025-11-24T15:00:00.123Z"
}
✅ Success! You've sent your first webhook!
🔧 Step 2: Minimal Integration (10 minutes)¶
Send real table session data with the absolute minimum required fields:
Python Example¶
import requests
from datetime import datetime
# Configuration
TOKEN = "YOUR_TOKEN_HERE" # Replace with your token
URL = f"https://api.emiliavision.com/webhooks/v1/pos/{TOKEN}?env=dev"
def send_table_session(order_id, table_number, start_time, end_time):
"""Send minimal table session data"""
payload = {
"event": "session_complete",
"order_id": order_id,
"table_number": table_number,
"session_start": start_time,
"session_end": end_time,
"timestamp": end_time
}
response = requests.post(URL, json=payload)
if response.status_code == 200:
print(f"✅ Session {order_id} sent successfully!")
return response.json()
else:
print(f"❌ Error: {response.status_code} - {response.text}")
return None
# Test it
send_table_session(
order_id="ORD-001",
table_number="Mesa 5",
start_time="2025-11-24T18:30:00-03:00",
end_time="2025-11-24T20:15:00-03:00"
)
Node.js Example¶
const axios = require('axios');
// Configuration
const TOKEN = 'YOUR_TOKEN_HERE'; // Replace with your token
const URL = `https://api.emiliavision.com/webhooks/v1/pos/${TOKEN}?env=dev`;
async function sendTableSession(orderId, tableNumber, startTime, endTime) {
const payload = {
event: 'session_complete',
order_id: orderId,
table_number: tableNumber,
session_start: startTime,
session_end: endTime,
timestamp: endTime
};
try {
const response = await axios.post(URL, payload);
console.log(`✅ Session ${orderId} sent successfully!`);
return response.data;
} catch (error) {
console.error(`❌ Error: ${error.message}`);
return null;
}
}
// Test it
sendTableSession(
'ORD-001',
'Mesa 5',
'2025-11-24T18:30:00-03:00',
'2025-11-24T20:15:00-03:00'
);
💰 Step 3: Add Financial Data (Day 1)¶
Enhance your webhook with totals and payment information:
def send_complete_session(order_data):
"""Send session with financial data"""
payload = {
"event": "session_complete",
"order_id": order_data["id"],
"table_number": order_data["table"],
"session_start": order_data["opened_at"],
"session_end": order_data["closed_at"],
"timestamp": order_data["closed_at"],
# Add financial data
"totals": {
"subtotal": order_data["subtotal"],
"tip": order_data["tip"],
"tax": order_data["tax"],
"total": order_data["total"]
},
# Add payment info
"payment": {
"method": order_data["payment_method"],
"fiscal_receipt": order_data["receipt_number"]
}
}
response = requests.post(URL, json=payload)
return response.json() if response.status_code == 200 else None
# Example usage
order = {
"id": "ORD-002",
"table": "Mesa 8",
"opened_at": "2025-11-24T19:00:00-03:00",
"closed_at": "2025-11-24T21:00:00-03:00",
"subtotal": 150.00,
"tip": 19.50,
"tax": 15.00,
"total": 184.50,
"payment_method": "VISA_CREDIT",
"receipt_number": "NFe35251133111140001168650020000762241540579084"
}
send_complete_session(order)
🍽️ Step 4: Add Item Details (Day 2)¶
Include what was ordered and when:
def send_session_with_items(order_data):
"""Send complete session with item details"""
payload = {
"event": "session_complete",
"order_id": order_data["id"],
"table_number": order_data["table"],
"session_start": order_data["opened_at"],
"session_end": order_data["closed_at"],
"timestamp": order_data["closed_at"],
# Add server information
"opened_by": {
"id": order_data["opened_by_id"],
"name": order_data["opened_by_name"]
},
"closed_by": {
"id": order_data["closed_by_id"],
"name": order_data["closed_by_name"]
},
# Add items with timestamps - THIS IS GOLD!
"items": [
{
"timestamp": item["ordered_at"],
"employee_id": item["server_id"],
"name": item["name"],
"quantity": item["qty"],
"price": item["price"]
}
for item in order_data["items"]
],
"totals": {
"subtotal": order_data["subtotal"],
"tip": order_data["tip"],
"tax": order_data["tax"],
"total": order_data["total"]
},
"payment": {
"method": order_data["payment_method"],
"fiscal_receipt": order_data["receipt_number"]
}
}
response = requests.post(URL, json=payload)
return response.json() if response.status_code == 200 else None
⚡ Step 5: Real-Time Updates (Week 2)¶
Graduate to sending events as they happen:
class EmiliaWebhook:
def __init__(self, token, env='dev'):
self.token = token
self.url = f"https://api.emiliavision.com/webhooks/v1/pos/{token}"
if env == 'dev':
self.url += "?env=dev"
def table_opened(self, order_id, table, server):
"""Send when table is seated"""
return self._send({
"event": "session_opened",
"timestamp": datetime.now().isoformat(),
"order_id": order_id,
"table_number": table,
"server": server
})
def items_ordered(self, order_id, table, items):
"""Send when items are added"""
return self._send({
"event": "items_added",
"timestamp": datetime.now().isoformat(),
"order_id": order_id,
"table_number": table,
"items": items
})
def table_closed(self, order_id, table, totals, payment):
"""Send when check is paid"""
return self._send({
"event": "session_closed",
"timestamp": datetime.now().isoformat(),
"order_id": order_id,
"table_number": table,
"totals": totals,
"payment": payment
})
def _send(self, payload):
try:
response = requests.post(self.url, json=payload, timeout=10)
response.raise_for_status()
return response.json()
except Exception as e:
print(f"Error: {e}")
return None
# Usage
webhook = EmiliaWebhook("YOUR_TOKEN", env='dev')
# When table opens
webhook.table_opened("ORD-003", "Mesa 12", {"id": 72, "name": "João"})
# When items ordered
webhook.items_ordered("ORD-003", "Mesa 12", [
{
"timestamp": datetime.now().isoformat(),
"employee_id": 72,
"name": "Carbonara",
"quantity": 2,
"price": 85.00
}
])
# When table closes
webhook.table_closed("ORD-003", "Mesa 12",
{"subtotal": 170.00, "tip": 22.10, "tax": 17.00, "total": 209.10},
{"method": "VISA_CREDIT"}
)
✅ Production Checklist¶
Before going to production:
Week 1: Basic Integration¶
- Successfully sending test webhooks to dev environment
- Sending table number and session times
- Receiving success responses consistently
- Basic error handling implemented
Week 2: Enhanced Data¶
- Adding financial totals
- Including item details
- Sending employee/server information
- Implementing retry logic for failures
Week 3: Production Ready¶
- Switch from
?env=devto production URL - Monitoring webhook success rate
- Logging all webhook attempts
- Alert system for failures
🎉 Success Milestones¶
Day 1: First Webhook ✅¶
curl -X POST "https://api.emiliavision.com/webhooks/v1/pos/TOKEN?env=dev" \
-H "Content-Type: application/json" \
-d '{"event":"test","table_number":"Mesa 1","timestamp":"2025-11-24T12:00:00-03:00"}'
Day 2: Real Data 📊¶
- Sending actual table sessions
- Including open/close times
- Basic financial data
Week 1: Rich Data 💎¶
- Item-level timestamps
- Employee tracking
- Complete financial breakdowns
Week 2: Real-Time 🚀¶
- Events sent as they happen
- Full operational visibility
- Production environment
🆘 Getting Stuck?¶
Quick Fixes¶
| Problem | Solution |
|---|---|
| 401 Error | Check your token is correct |
| No response | Add ?env=dev for testing |
| 413 Error | Reduce payload size |
| Timeout | Increase timeout to 30 seconds |
Test Your Connection¶
# Simple connection test
import requests
TOKEN = "YOUR_TOKEN"
url = f"https://api.emiliavision.com/webhooks/v1/pos/{TOKEN}?env=dev"
test_payload = {
"event": "connection_test",
"timestamp": "2025-11-24T12:00:00-03:00",
"table_number": "Test"
}
response = requests.post(url, json=test_payload)
print(f"Status: {response.status_code}")
print(f"Response: {response.text}")
Get Help¶
- Quick questions: team@emiliavision.com
- Integration support: team@emiliavision.com
- Response time: Usually < 4 hours
🎯 Remember¶
- Start simple - Just table number and times
- Test in dev - Use
?env=devparameter - Add data gradually - Don't try everything at once
- The most important field is
table_number- This links to our video analytics - Item timestamps are gold - They provide incredible insights
📈 What Happens Next?¶
Once you're sending webhooks:
- Within 5 minutes: Data appears in dev dashboard
- Within 1 hour: Initial analytics available
- Within 24 hours: Full correlation with video data
- Within 1 week: Operational insights and recommendations
Ready to start? Send your first test webhook now! It takes just 30 seconds with the cURL command above.
Need a token? Email team@emiliavision.com - we'll have one for you within 24 hours.