Logo
Search
API Docs

E-Commerce Order Management Squad

Guides

E-Commerce Order Management: A Squad Walkthrough

Overview

This is a full worked example of building an e-commerce customer-service system as a Squad — three specialized assistants sharing a phone number and handing calls off between each other — using the same underlying mechanics covered in Squad API: Create, Update, List, Squad Routing: Handoff Destinations & Context Engineering, and Files API. A modern Squad-based approach like this one has superseded the older Workflow-based way of building multi-step call flows, so this walkthrough only covers the Squad approach.


Step 1: Upload the Knowledge Base Files

Upload four CSV files through the Files API:

  • customers.csv — columns: customer_id, name, phone, email, tier, lifetime_value
  • orders.csv — order history, status, and delivery details
  • products.csv — product catalog details
  • returns.csv — return eligibility windows and prior return history
curl --location 'https://api.sulus.ai/file' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--form 'file=@"customers.csv"'

# repeat for orders.csv, products.csv, and returns.csv

Save each returned file id for use in the tools below. See Files API for the complete field reference.


Step 2: Create the Three Tools

Create three function tools, each backed by the relevant knowledge base and, where noted, an external server:

ToolPurposeBackend
lookup_customerVerifies the caller and retrieves their tier and order historycustomers.csv knowledge base
track_orderReturns live shipping status for an orderPoints to your shipping provider's own server URL
process_returnChecks return eligibility and initiates a returnPoints to your returns system's own server URL
curl -X POST "https://api.sulus.ai/tool" \
  -H "Authorization: Bearer $CORE_SYSTEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "function",
    "name": "track_order",
    "description": "Look up live shipping status for a customer order",
    "parameters": {
      "type": "object",
      "properties": {
        "orderId": { "type": "string", "description": "The order ID to track" }
      },
      "required": ["orderId"]
    },
    "server": {
      "url": "https://your-shipping-provider.example.com/track"
    }
  }'

See Custom Function Tools for the full field reference on defining a tool this way.


Step 3: Build the Three-Assistant Squad

Define the squad with three members — Orders, Returns, and VIP — each with its own focused system prompt and tools:

curl -X POST https://api.sulus.ai/squad \
  -H "Authorization: Bearer $CORE_SYSTEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "E-Commerce Support Squad",
    "members": [
      {
        "assistant": {
          "name": "Orders",
          "model": {
            "provider": "openai",
            "model": "gpt-4o",
            "messages": [{ "role": "system", "content": "Orders specialist. Handle tracking and delivery questions using lookup_customer and track_order." }],
            "toolIds": ["LOOKUP_CUSTOMER_ID", "TRACK_ORDER_ID"]
          },
          "firstMessage": "Hello, how can I help with your order today?",
          "firstMessageMode": "assistant-speaks-first"
        },
        "assistantDestinations": [
          {
            "type": "assistant",
            "assistantName": "Returns",
            "description": "Customer wants to return an item or asks about a refund.",
            "contextEngineeringPlan": { "type": "all" }
          },
          {
            "type": "assistant",
            "assistantName": "VIP",
            "description": "Customer is a high-value/VIP tier customer, or is expressing frustration or negative sentiment.",
            "contextEngineeringPlan": { "type": "all" }
          }
        ]
      },
      {
        "assistant": {
          "name": "Returns",
          "model": {
            "provider": "openai",
            "model": "gpt-4o",
            "messages": [{ "role": "system", "content": "Returns specialist. Check eligibility and process the return using process_return." }],
            "toolIds": ["PROCESS_RETURN_ID"]
          }
        },
        "assistantDestinations": [
          {
            "type": "assistant",
            "assistantName": "VIP",
            "description": "Customer is a high-value/VIP tier customer, or is expressing frustration or negative sentiment.",
            "contextEngineeringPlan": { "type": "all" }
          }
        ]
      },
      {
        "assistant": {
          "name": "VIP",
          "model": {
            "provider": "openai",
            "model": "gpt-4o",
            "messages": [{ "role": "system", "content": "VIP concierge. Prioritize premium customers, resolve issues directly, and coordinate with order/return data as needed." }],
            "toolIds": ["LOOKUP_CUSTOMER_ID", "TRACK_ORDER_ID", "PROCESS_RETURN_ID"]
          }
        }
      }
    ]
  }'

See Squad API: Create, Update, List for the full request/response reference for this endpoint.


Transfer Rules Between Assistants

FromToTrigger
OrdersReturnsCustomer asks to return an item
OrdersVIPCustomer is high-value, or sentiment turns negative
ReturnsVIPCustomer is high-value, or sentiment turns negative

Each destination's description is the actual routing logic the model reasons over — write it as a specific triggering condition, not a generic label. See Squad Routing: Handoff Destinations & Context Engineering for the full field reference, including the contextEngineeringPlan options used above to carry full conversation history forward on every transfer.


Testing the Squad

Attach a phone number to the squad, then call it and simulate each scenario end to end:

  • Ask about an existing order's shipping status — confirm the Orders assistant answers directly without transferring
  • Ask to return an item — confirm a clean handoff from Orders to Returns
  • Call in as a high-value or visibly frustrated customer — confirm a transfer to VIP from either Orders or Returns

Listen for whether context (the order or return already discussed) carries over cleanly after each transfer, since every destination above uses contextEngineeringPlan: { "type": "all" }.