### Voice Agent Instructions Example Source: https://context7.com/softboom-srl/yourang-docs/llms.txt This is an example of plain text instructions for a voice agent, defining its role, capabilities, escalation triggers, security protocols, and fallback behavior. ```text # Example instructions for a hotel reception agent You are Sofia, the virtual receptionist for Hotel Bella Vista. Greet callers with: "Good morning, I'm Sofia, the voice assistant for Hotel Bella Vista. I can help you with bookings, room information, and on-site services." ## What you can do - Provide information about room types, rates, and availability - Accept, modify, or cancel reservations (check-in date, room type, number of guests) - Answer questions about hotel services (pool, restaurant, parking, pets) - Transfer to the appropriate department when needed ## When to transfer - Customer requests to speak with a human → transfer to Reception department - Billing disputes or complaints → transfer to Management department - Restaurant table bookings for hotel guests → transfer to Dining department ## Security - Never ask for credit card details or passwords - Never share another guest's personal data ## When you don't understand Ask the customer to repeat once. If still unclear, say: "I'm sorry, I wasn't able to fully understand your request. I'll transfer you to a colleague who can help you directly." Then transfer to Reception. ``` -------------------------------- ### Example External Tool Request and Response Source: https://github.com/softboom-srl/yourang-docs/blob/main/voice-agent/external-tools.md This example shows a POST request to a lookup-customer tool with relevant payload data and the expected JSON response when a customer is found. Ensure your tool endpoint handles these parameters and returns a structured response. ```json POST /tools/lookup-customer { "phone": "+1 415 555 0142", "call_id": "cl_abc123", "organization_id": "org_xyz" } # Expected response (200 OK): { "found": true, "customer": { "name": "Jane Doe", "tier": "gold", "last_order_date": "2026-03-12" } } ``` -------------------------------- ### FastAPI CRM Lookup Tool Source: https://context7.com/softboom-srl/yourang-docs/llms.txt Example of a FastAPI server exposing a CRM lookup tool for the voice agent. The agent invokes this tool with call context and receives customer data. ```python from fastapi import FastAPI, Request from pydantic import BaseModel app = FastAPI() class LookupRequest(BaseModel): phone: str call_id: str organization_id: str @app.post("/tools/lookup-customer") async def lookup_customer(body: LookupRequest): # Query your internal CRM by phone number customer = db.find_by_phone(body.phone) if not customer: return {"found": False} return { "found": True, "customer": { "name": customer.full_name, "tier": customer.loyalty_tier, # "gold", "silver", "standard" "last_order_date": str(customer.last_order.date()), "outstanding_balance": customer.balance, } } # Yourang POSTs this when the agent decides to invoke the tool: # { # "phone": "+1 415 555 0142", # "call_id": "cl_abc123", # "organization_id": "org_xyz" # } # # The agent receives the JSON response and uses it to personalize the reply. ``` -------------------------------- ### Availability Rules Configuration Example Source: https://context7.com/softboom-srl/yourang-docs/llms.txt This JSON structure defines availability rules for a business, including weekly operating hours, specific service times with slot durations and capacities, closure dates, and party size limits. This configuration is managed via the Bookings → Availability Rules panel. ```json // Example availability configuration (as managed in the Yourang panel) { "business_type": "restaurant", "weekly_hours": { "monday": { "open": "12:00", "close": "22:00" }, "tuesday": { "open": "12:00", "close": "22:00" }, "wednesday": { "open": "12:00", "close": "22:00" }, "thursday": { "open": "12:00", "close": "23:00" }, "friday": { "open": "12:00", "close": "23:30" }, "saturday": { "open": "11:00", "close": "23:30" }, "sunday": { "open": "11:00", "close": "22:00" } }, "services": [ { "name": "Lunch", "start": "12:00", "end": "14:00", "slot_minutes": 90, "capacity_covers": 50 }, { "name": "Dinner", "start": "19:00", "end": "22:00", "slot_minutes": 90, "capacity_covers": 50 } ], "closure_dates": ["2024-12-25", "2024-01-01"], "min_party_size": 1, "max_party_size": 12 } ``` -------------------------------- ### List Contacts using cURL Source: https://github.com/softboom-srl/yourang-docs/blob/main/external-api/endpoints.md Use this cURL command to make a GET request to list contacts with a limit of 20. Ensure you replace 'yr_live_xxx' with your actual API key. ```bash curl -X GET "https://api.Yourang.io/external/v1/contacts?limit=20" \ -H "Authorization: Bearer yr_live_xxx" \ -H "Accept: application/json" ``` -------------------------------- ### Express.js Webhook Receiver Source: https://context7.com/softboom-srl/yourang-docs/llms.txt Example of an Express.js server to receive and verify Yourang webhook events. Respond with 200 OK immediately to process asynchronously. ```javascript import express from "express"; import crypto from "crypto"; const app = express(); app.use(express.json()); // Available events: // call.ended | reservation.created | reservation.modified | reservation.cancelled // order.created | order.updated | contact.created | contact.updated // evaluation.outcome | workflow.completed app.post("/webhooks/yourang", (req, res) => { const signature = req.headers["x-yourang-signature"]; const secret = process.env.YOURANG_WEBHOOK_SECRET; const expected = crypto .createHmac("sha256", secret) .update(JSON.stringify(req.body)) .digest("hex"); if (signature !== `sha256=${expected}`) { return res.status(401).send("Invalid signature"); } // Respond 200 immediately; process asynchronously res.sendStatus(200); const { event_id, event, data } = req.body; console.log(`[${event_id}] ${event}`, data); // Example: call.ended payload // { // "event_id": "evt_abc123", // "event": "call.ended", // "data": { // "call_sid": "cl_xyz", // "duration_seconds": 142, // "outcome": "transferred", // "transcript": "Customer: I need a table for two tonight...", // "summary": "Customer requested dinner reservation for 2 on June 12." // } // } }); app.listen(3000); ``` -------------------------------- ### Department Routing Configuration Example Source: https://context7.com/softboom-srl/yourang-docs/llms.txt This JSON array defines departments for human escalation, including their name, phone number, operating hours, expertise description for AI routing, and priority. The system uses this to route calls, with fallback options for after-hours or unavailable departments. ```json // Example department configuration for a hotel [ { "name": "Reception", "phone": "+39 02 1234567 ext 1", "hours": { "mon-sun": "07:00-23:00" }, "expertise": "Check-in, check-out, room keys, general information, loyalty programme", "priority": 1 }, { "name": "Dining", "phone": "+39 02 1234567 ext 2", "hours": { "mon-sun": "11:30-22:30" }, "expertise": "Restaurant table reservations, menu, food allergies and intolerances", "priority": 2 }, { "name": "Management", "phone": "+39 02 1234567 ext 0", "hours": { "mon-fri": "09:00-18:00" }, "expertise": "Complaints, billing disputes, corporate events, special VIP requests", "priority": 3 } ] // After-hours fallback: // If a department is outside its hours, the agent escalates to the next by priority. // If none is available, the after-hours flow activates (voicemail or WhatsApp follow-up). ``` -------------------------------- ### List Contacts using Node.js Source: https://github.com/softboom-srl/yourang-docs/blob/main/external-api/endpoints.md This Node.js snippet demonstrates how to fetch a list of contacts using the 'node-fetch' library. It makes a GET request and logs the number of contacts retrieved. Replace 'yr_live_xxx' with your API key. ```javascript import fetch from "node-fetch"; const res = await fetch( "https://api.Yourang.io/external/v1/contacts?limit=20", { headers: { Authorization: "Bearer yr_live_xxx", Accept: "application/json", }, } ); const { data } = await res.json(); console.log(`Got ${data.length} contacts`); ``` -------------------------------- ### List Contacts using Python Source: https://github.com/softboom-srl/yourang-docs/blob/main/external-api/endpoints.md This Python script uses the 'requests' library to retrieve a list of contacts. It includes a timeout and error handling for the GET request. Remember to substitute 'yr_live_xxx' with your API key. ```python import requests resp = requests.get( "https://api.Yourang.io/external/v1/contacts", params={"limit": 20}, headers={ "Authorization": "Bearer yr_live_xxx", "Accept": "application/json", }, timeout=10, ) resp.raise_for_status() print(f"Got {len(resp.json()['data'])} contacts") ``` -------------------------------- ### Get Contact Source: https://context7.com/softboom-srl/yourang-docs/llms.txt Retrieves a single contact by their unique identifier (UUID). Returns a 404 error if the contact is not found or does not belong to the authenticated organization. ```APIDOC ## Get Contact — `GET /v1/contacts/{contact_id}` Retrieves a single contact by UUID. Returns 404 if the contact does not exist or belongs to a different organization. ```bash curl -X GET "https://api.yourang.ai/v1/contacts/550e8400-e29b-41d4-a716-446655440000" \ -H "Authorization: Bearer yr_live_abc123" # 200 OK { "ok": true, "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@example.com", "phone_number": "+1 415 555 0142", "address": "123 Market St, San Francisco, CA", "last_call_time": "2024-06-11T09:00:00Z" } } # 404 Not Found { "ok": false, "error": "Contact not found" } ``` ``` -------------------------------- ### Minimal MCP Server in Python (FastAPI) Source: https://context7.com/softboom-srl/yourang-docs/llms.txt This snippet shows a basic FastAPI application that handles MCP requests for tool discovery and invocation. It requires the FastAPI library and supports a 'check_room_availability' tool. ```python from fastapi import FastAPI, Request from fastapi.responses import JSONResponse import uuid app = FastAPI() TOOLS = [ { "name": "check_room_availability", "description": "Check if a room type is available for given dates.", "inputSchema": { "type": "object", "properties": { "room_type": {"type": "string", "enum": ["double", "twin", "suite"]}, "check_in": {"type": "string", "format": "date"}, "check_out": {"type": "string", "format": "date"}, }, "required": ["room_type", "check_in", "check_out"], }, } ] @app.post("/mcp") async def mcp_handler(request: Request): body = await request.json() method = body.get("method") req_id = body.get("id") # Discovery if method == "tools/list": return JSONResponse( content={"jsonrpc": "2.0", "id": req_id, "result": {"tools": TOOLS}}, headers={"Mcp-Session-Id": str(uuid.uuid4())}, ) # Invocation if method == "tools/call": tool_name = body["params"]["name"] args = body["params"]["arguments"] caller = body["params"].get("_meta", {}).get("caller", {}) # caller = { call_sid, agent_id, organization_id, phone, name, email, contact_id } if tool_name == "check_room_availability": available = pms.check(args["room_type"], args["check_in"], args["check_out"]) text = f"Room type '{args['room_type']}' is {'available' if available else 'not available'} for those dates." return {"jsonrpc": "2.0", "id": req_id, "result": {"content": [{"type": "text", "text": text}]}} return {"jsonrpc": "2.0", "id": req_id, "error": {"code": -32601, "message": "Method not found"}} # HTTP headers Yourang sends on every request: # Content-Type: application/json # Accept: application/json, text/event-stream # Mcp-Session-Id: # Authorization: Bearer (if configured) ``` -------------------------------- ### Perform Health Check on Yourang API Source: https://context7.com/softboom-srl/yourang-docs/llms.txt Use the GET /v1/health endpoint to verify the external API is operational. No authentication is required, making it suitable for liveness probes in deployment pipelines. ```bash curl -X GET "https://api.yourang.ai/v1/health" ``` ```json # 200 OK { "ok": true, "data": { "status": "healthy", "api_version": "v1", "service": "external_api" } } ``` -------------------------------- ### Incoming Webhooks (Outbound from Yourang) Source: https://context7.com/softboom-srl/yourang-docs/llms.txt Register a public HTTPS endpoint to receive event notifications from Yourang. Yourang POSTs a signed JSON payload for each subscribed event. Respond with `200 OK` immediately and process events asynchronously. ```APIDOC ## Incoming Webhooks ### Description Register a public HTTPS endpoint in Administration → API → Webhooks and select the events to subscribe to. Yourang POSTs a signed JSON payload to the URL for each event. Respond `200 OK` immediately and process asynchronously. Each payload carries a unique ID — use it for idempotency on retries. ### Available Events - `call.ended` - `reservation.created` - `reservation.modified` - `reservation.cancelled` - `order.created` - `order.updated` - `contact.created` - `contact.updated` - `evaluation.outcome` - `workflow.completed` ### Request Example (Express.js) ```javascript import express from "express"; import crypto from "crypto"; const app = express(); app.use(express.json()); app.post("/webhooks/yourang", (req, res) => { const signature = req.headers["x-yourang-signature"]; const secret = process.env.YOURANG_WEBHOOK_SECRET; const expected = crypto .createHmac("sha256", secret) .update(JSON.stringify(req.body)) .digest("hex"); if (signature !== `sha256=${expected}`) { return res.status(401).send("Invalid signature"); } // Respond 200 immediately; process asynchronously res.sendStatus(200); const { event_id, event, data } = req.body; console.log(`[${event_id}] ${event}`, data); }); app.listen(3000); ``` ### Payload Example (`call.ended`) ```json { "event_id": "evt_abc123", "event": "call.ended", "data": { "call_sid": "cl_xyz", "duration_seconds": 142, "outcome": "transferred", "transcript": "Customer: I need a table for two tonight...", "summary": "Customer requested dinner reservation for 2 on June 12." } } ``` ``` -------------------------------- ### Trigger Yourang Workflow via HTTP Request (n8n) Source: https://context7.com/softboom-srl/yourang-docs/llms.txt This JavaScript snippet demonstrates how to use an n8n HTTP Request node to send a webhook trigger to Yourang. It includes an example payload for a 'checkout_completed' event. ```javascript // n8n HTTP Request node — fire a Yourang webhook trigger // Configure this node in an n8n workflow to kick off a Yourang automation // when an event occurs in your external system (e.g., PMS checkout). const workflowWebhookUrl = "https://hooks.yourang.ai/wh_abc123xyz"; const response = await $http.post(workflowWebhookUrl, { body: { event: "checkout_completed", reservation_id: "RES-20240612-001", guest_name: "Mario Rossi", guest_phone: "+39 333 1234567", guest_email: "mario.rossi@example.com", checkout_date: "2024-06-12", room: "Suite 301", }, headers: { "Content-Type": "application/json" }, }); // Yourang receives the payload and starts the mapped workflow, e.g.: // Workflow 3 — post-stay sequence: // 1. Wait 4 hours // 2. Send thank-you email with property photos // 3. Wait 3 days → send review-request email // 4. Wait 30 days → if no review → send discount code ``` -------------------------------- ### MCP Discovery Request (tools/list) Source: https://github.com/softboom-srl/yourang-docs/blob/main/voice-agent/mcp.md This is the JSON-RPC 2.0 request sent by Yourang to discover available tools on an MCP server. It's a standard POST request with an empty params object. ```json { "jsonrpc": "2.0", "method": "tools/list", "params": {}, "id": "" } ``` -------------------------------- ### List Contacts (Python) Source: https://github.com/softboom-srl/yourang-docs/blob/main/external-api/endpoints.md This snippet shows how to list contacts using Python's requests library. Replace 'yr_live_xxx' with your personal API key. ```APIDOC ## GET /external/v1/contacts (Python) ### Description Retrieves a list of contacts using Python. Replace `yr_live_xxx` with your personal API key. ### Method GET ### Endpoint /external/v1/contacts ### Parameters #### Query Parameters - **limit** (integer) - Optional - The maximum number of contacts to return. #### Headers - **Authorization** (string) - Required - Bearer token for authentication (e.g., "Bearer yr_live_xxx"). - **Accept** (string) - Optional - Specifies the desired response format, typically "application/json". ### Request Example ```python import requests resp = requests.get( "https://api.Yourang.io/external/v1/contacts", params={"limit": 20}, headers={ "Authorization": "Bearer yr_live_xxx", "Accept": "application/json", }, timeout=10, ) resp.raise_for_status() print(f"Got {len(resp.json()['data'])} contacts") ``` ### Response #### Success Response (200) - **data** (array) - A list of contact objects. #### Response Example ```json { "data": [ { "id": "contact_id_1", "name": "John Doe", "email": "john.doe@example.com", "phone": "123-456-7890" } ], "pagination": { "limit": 20, "offset": 0, "total": 100 } } ``` ``` -------------------------------- ### List Contacts (Node.js) Source: https://github.com/softboom-srl/yourang-docs/blob/main/external-api/endpoints.md This snippet demonstrates how to list contacts using Node.js's fetch API. Replace 'yr_live_xxx' with your personal API key. ```APIDOC ## GET /external/v1/contacts (Node.js) ### Description Retrieves a list of contacts using Node.js. Replace `yr_live_xxx` with your personal API key. ### Method GET ### Endpoint /external/v1/contacts ### Parameters #### Query Parameters - **limit** (integer) - Optional - The maximum number of contacts to return. #### Headers - **Authorization** (string) - Required - Bearer token for authentication (e.g., "Bearer yr_live_xxx"). - **Accept** (string) - Optional - Specifies the desired response format, typically "application/json". ### Request Example ```javascript import fetch from "node-fetch"; const res = await fetch( "https://api.Yourang.io/external/v1/contacts?limit=20", { headers: { Authorization: "Bearer yr_live_xxx", Accept: "application/json", }, } ); const { data } = await res.json(); console.log(`Got ${data.length} contacts`); ``` ### Response #### Success Response (200) - **data** (array) - A list of contact objects. #### Response Example ```json { "data": [ { "id": "contact_id_1", "name": "John Doe", "email": "john.doe@example.com", "phone": "123-456-7890" } ], "pagination": { "limit": 20, "offset": 0, "total": 100 } } ``` ```