A TypeScript backend that bridges voice AI systems (Pipecat) with NCR Aloha POS via the BSP (Business Services Platform) APIs.
[Phone/Browser] → [Daily.co WebRTC] → [Pipecat] → [TypeScript API] → [NCR Aloha]
or or
[Real Phone] → [Telnyx VOIP/SIP] → ↓
Deepgram STT → GPT-4o → Cartesia TTS
ncr-backend(port 3000): TypeScript Express APIncr-pipecat(port 8765): Python voice bot server
npm install
npm run dev # Start with hot reload
npm run server # Start server oncecd web
npm install
npm run dev# Terminal 1
npm run server # Backend on :3000
# Terminal 2
cd web && npm run dev # Frontend on :5173The frontend proxies /api/* requests to localhost:3000.
# Standard deployment (free-form conversation)
docker compose up -d --build
# With Pipecat Flows (structured conversation)
USE_FLOWS=true docker compose up -d --build
# View logs
docker logs ncr-pipecat --tail 50 -f
docker logs ncr-backend --tail 50 -fsrc/
├── auth/hmac.ts # HMAC-SHA512 authentication for NCR APIs
├── api/
│ ├── client.ts # Base HTTP client with auto-auth
│ ├── orders.ts # Order API endpoints
│ └── catalog.ts # Catalog API endpoints
├── services/
│ ├── order-service.ts # High-level order processing
│ ├── order-builder.ts # Converts VoiceOrder → NCR Order
│ └── menu-matcher.ts # Fuzzy matching spoken items to menu
├── models/
│ ├── order.ts # NCR order types
│ ├── catalog.ts # NCR catalog types
│ └── menu.ts # VoiceOrder and Menu types
├── data/
│ └── allstar-menu.ts # Sample menu data
├── config/index.ts # Environment configuration
├── server.ts # Express server
└── index.ts # Library exports
- React 19 + Vite + TypeScript
- Tailwind CSS v4 with shadcn/ui components
- Components:
MenuItemCard,ItemConfigDialog,Cart - Hooks:
useMenu,useCart
- Voice AI produces a
VoiceOrder(customer info, items with spoken names) MenuMatcherfuzzy-matches spoken items to actual menu itemsOrderBuilderconverts to NCRCreateOrderRequestformatOrderService.submitOrder()sends to NCR API
{
orderType: "pickup" | "delivery",
items: [{ itemName: string, quantity: number, size?: string, modifiers?: string[] }],
customer: { name: string, phone: string }
}Get free test API keys (valid for 30 days) from the NCR Voyix Developer Portal.
NCR_API_GATEWAY=https://api.ncr.com
NCR_ORGANIZATION=<org-id>
NCR_SITE_ID=<site-id>
NCR_SHARED_KEY=<shared-key>
NCR_SECRET_KEY=<secret-key>
# Transport (choose one or both)
DAILY_API_KEY= # WebRTC rooms (https://dashboard.daily.co)
TELNYX_API_KEY= # VOIP/SIP telephony (https://portal.telnyx.com)
# AI Services
DEEPGRAM_API_KEY= # Speech-to-text (https://console.deepgram.com)
OPENAI_API_KEY= # LLM - GPT-4o (https://platform.openai.com)
CARTESIA_API_KEY= # Text-to-speech (https://cartesia.ai)
CARTESIA_VOICE_ID= # Voice ID for TTS
# Backend
ORDER_API_URL=http://localhost:3000
# Production
PUBLIC_URL=https://your-domain.com # Required for Telnyx WebSocket URL
Python-based voice AI that connects to the TypeScript API.
| Bot | Transport | Conversation Style | File |
|---|---|---|---|
| Daily.co | WebRTC (browser) | Structured states | bot_flows.py |
| Telnyx | VOIP/SIP (phone) | Structured states | server_telnyx_flows.py |
All bots use the Flows architecture with enforced conversation states:
greeting → order_collection → order_confirmation → customer_info → completion
Windows (text-based testing only):
cd pipecat
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
python test_order.pyWSL/Linux/Mac (full voice mode):
cd pipecat
source venv/bin/activate
pip install 'pipecat-ai[daily,openai,deepgram,cartesia,silero]' pipecat-ai-flows httpx python-dotenv pydantic# Text-based testing (Windows)
python test_order.py
# Daily.co WebRTC bot
python create_room.py # Get room URL
python bot_flows.py <room_url>
# Telnyx VOIP (real phone calls)
python server_telnyx_flows.py
# HTTP server for session management
python server.py # Runs on port 8765# Create session
curl -X POST http://localhost:8765/sessions
# Get session status
curl http://localhost:8765/sessions/{session_id}
# Health check
curl http://localhost:8765/health| Feature | Description |
|---|---|
| SmartTurnAnalyzer | AI-powered turn detection for natural pauses |
| Silero VAD | Optimized voice activity detection |
| Idle Detection | Auto-end calls after 5 min silence |
| Call Recording | Optional recording via Daily.co |
| Call Metrics | Track duration, turns, order success |
POST /order/3/orders/1- Create orderGET /order/3/orders/1/{id}- Get orderPOST /order/3/orders/1/find- Find ordersPOST /catalog/v2/items- Catalog operations
All NCR API requests require HMAC-SHA512 signed headers:
- HTTP method + URL path + content-type + organization
- Signed with:
secretKey + ISO timestamp - Header format:
Authorization: AccessKey {sharedKey}:{base64Signature}
- Channel:
PhoneIn,Web,Mobile,WalkIn,DriveThru,CallCenter,Other - Order Status:
OrderPlaced,OrderReceived,InProgress,ReadyForPickup,Completed,Cancelled - Total Type:
TaxExcluded,TaxIncluded,Net
- Create account at https://portal.telnyx.com
- Get API key from Settings → API Keys
- Buy a phone number with Voice capability
- Create TeXML Application:
- Go to Voice → TeXML Apps
- Create new app with this TeXML:
<?xml version="1.0" encoding="UTF-8"?> <Response> <Connect> <Stream url="wss://your-server.com/ws" bidirectionalMode="rtp"></Stream> </Connect> <Pause length="40"/> </Response>
- Assign TeXML app to your phone number
- For local testing: use ngrok (
ngrok http 8765) and update the TeXML URL
MIT