Agent Configuration

Configure multi-tenant settings, security controls, widget keys, and deploy your voice agent to production.

Agent Configuration: From Design to Deployment

You've designed your agent, crafted the prompt, and built the tools. Now it's time to configure the multi-tenant architecture, set security controls, and deploy your agent to your website.

VOX's configuration model supports multiple businesses (tenants), each with their own agents, widget keys, rate limits, and security settings — all managed from a centralized system.

The Multi-Tenant Configuration Model

Every deployment follows this hierarchy:

Platform
  └── Tenant (Your Business)
      ├── Agent Settings
      ├── Widget Keys
      ├── Rate Limits
      ├── API Secrets
      └── Billing & Identity

Tenant: Your Business Entity

A tenant represents a single business or customer using the VOX platform. Each tenant has complete isolation from others — their data, agents, and configurations are private.

Tenant Object Structure:

{
  "tenantId": "cypress-resorts",
  "name": "Cypress Resorts",
  "status": "trial",

  "identity": {
    "legalName": "Cypress Resorts Inc",
    "displayName": "Cypress Resorts",
    "domain": "cypressresort.com",
    "industry": "hospitality",
    "timeZone": "America/New_York",
    "locale": "en-US"
  },

  "contacts": {
    "primary": {
      "name": "John Doe",
      "email": "john@cypressresort.com",
      "phone": "+1-555-123-4567",
      "role": "Owner"
    },
    "billing": {
      "email": "billing@cypressresort.com"
    },
    "technical": {
      "email": "tech@cypressresort.com"
    }
  },

  "agentSettings": [
    {
      "agentId": "concierge",
      "label": "Cypress Concierge",
      "agentRepo": {
        "provider": "github",
        "baseRawUrl": "https://raw.githubusercontent.com/your-org/agents/main/AGENT_CYPRESS.md"
      }
    }
  ],

  "widgetKeys": [
    {
      "id": "main-site",
      "key": "w_cypress_main_7f1b0e9c64f54d1a",
      "origin": "https://cypressresort.com",
      "label": "Main marketing site",
      "revoked": false
    }
  ],

  "limits": {
    "maxAgents": 5,
    "maxConcurrentCalls": 20,
    "maxMonthlyMinutes": 2000,
    "maxRequestsPerMinute": 60
  },

  "flags": {
    "betaFeatures": false,
    "allowExperimentalModels": false
  },

  "createdAt": "2025-01-10T00:00:00Z",
  "updatedAt": "2025-01-15T00:00:00Z"
}

Agent Settings

Link your agent configuration (prompt + tools) to the tenant.

Basic Agent Setting

{
  "agentId": "concierge",
  "label": "Cypress Concierge",
  "agentRepo": {
    "provider": "github",
    "baseRawUrl": "https://raw.githubusercontent.com/your-org/agents/main/AGENT_CYPRESS.md"
  }
}

Fields Explained:

FieldPurposeExample
agentIdUnique identifier for this agent"concierge", "sales-bot"
labelHuman-readable name"Cypress Concierge"
agentRepo.providerWhere the agent config is stored"github" (or omit for database storage)
agentRepo.baseRawUrlURL to the agent markdown fileGitHub raw content URL

Agent Configuration Storage Options

You have two options for storing agent configurations (prompt + tools):

GitHub (Recommended)

Store agent configs as markdown files in a Git repo for version control, branching, and collaboration

Database

Store configs directly in MongoDB for simpler setups without Git dependency

GitHub Approach:

  • Store your agent definition as AGENT_TENANTID.md in a repo
  • Use raw GitHub URLs to fetch configs at runtime
  • Benefits: version history, rollback, staging vs production branches
  • VOX caches fetched configs for performance

Database Approach:

  • Store prompt and tools as JSON documents in MongoDB
  • Simpler for prototypes
  • Less infrastructure but no built-in versioning

Widget Keys: Secure Embedding

Widget keys control where your agent can be embedded. Each key is tied to a specific origin (domain) for security.

How Widget Keys Work

  1. You generate a widget key for each website/domain
  2. The key is embedded in the widget script on your site
  3. When users start a voice session, VOX verifies:
    • The key is valid and not revoked
    • The origin (website URL) matches the configured origin
    • The tenant is active and within limits

If any check fails, the session is rejected with a CORS error or unauthorized response.

Widget Key Structure

{
  "id": "main-site",
  "key": "w_cypress_main_7f1b0e9c64f54d1a",
  "origin": "https://cypressresort.com",
  "label": "Main marketing site",
  "revoked": false
}

Important Security Notes:

  • Origin must match exactly: https://cypressresort.comhttps://www.cypressresort.com
  • Add separate keys for www and non-www versions if needed
  • Use different keys for staging (https://staging.cypressresort.com) and production
  • Never share widget keys across tenants
  • Revoke compromised keys immediately by setting revoked: true

Multiple Widget Keys

A single tenant can have multiple widget keys for different sites or environments:

{
  "widgetKeys": [
    {
      "id": "production",
      "key": "w_cypress_prod_abc123",
      "origin": "https://cypressresort.com",
      "label": "Production site"
    },
    {
      "id": "staging",
      "key": "w_cypress_staging_def456",
      "origin": "https://staging.cypressresort.com",
      "label": "Staging environment"
    },
    {
      "id": "mobile",
      "key": "w_cypress_mobile_ghi789",
      "origin": "https://mobile.cypressresort.com",
      "label": "Mobile app web view"
    }
  ]
}

Rate Limits and Quotas

Protect your costs and prevent abuse with configurable limits at multiple layers.

Tenant-Level Limits

{
  "limits": {
    "maxAgents": 5,
    "maxConcurrentCalls": 20,
    "maxMonthlyMinutes": 2000,
    "maxRequestsPerMinute": 60
  }
}
LimitWhat It ControlsTypical ValueNotes
maxAgentsNumber of agents this tenant can create3-10Usually matches billing plan
maxConcurrentCallsMax simultaneous voice sessions10-50Prevents runaway costs; adjust based on traffic
maxMonthlyMinutesTotal voice minutes per month500-5000Tied to billing tier
maxRequestsPerMinuteAPI calls per minute60-180Prevents scripted abuse

Platform-Wide Rate Limits

VOX enforces additional limits at the platform level to protect infrastructure:

Edge Middleware (Fast Rejection):

  • IP-based rate limiting (60 requests/min by default)
  • User-based rate limiting (120 requests/min for authenticated users)
  • Bot detection and blocking

Server-Side (Authoritative):

  • Per-session quotas (tokens and dollars)
  • Daily spending caps per tenant
  • Session duration limits (15 minutes typical)
  • Idle timeout (5 minutes no activity)

Session Lifecycle:

1. User clicks voice widget
2. Edge checks IP rate limit → Pass
3. Server checks widget key + origin → Valid
4. Server checks concurrent sessions → Under limit
5. Session created → Monitor usage
6. Heartbeat every 45s → Update lastSeenAt
7. Session ends when:
   - User hangs up
   - Duration exceeds maxSessionMinutes
   - Idle exceeds maxSessionIdleSec
   - Daily quota exceeded
Small Business / Trial

maxConcurrentCalls: 10, maxMonthlyMinutes: 500, maxRequestsPerMinute: 30

Mid-Market

maxConcurrentCalls: 25, maxMonthlyMinutes: 2000, maxRequestsPerMinute: 60

Enterprise

maxConcurrentCalls: 100+, maxMonthlyMinutes: 10000+, maxRequestsPerMinute: 180

API Secrets Management

Store sensitive credentials securely and reference them in tool descriptors.

Adding Secrets to Tenant

{
  "tenantId": "cypress-resorts",
  "secrets": {
    "hotel_api_key": "sk_live_abc123...",
    "stripe_secret_key": "sk_test_xyz789...",
    "sendgrid_api_key": "SG.def456..."
  }
}

Using Secrets in Tools

Reference secrets in tool HTTP headers or body templates:

{
  "http": {
    "method": "POST",
    "urlTemplate": "https://your-api.com/booking",
    "headers": {
      "authorization": "Bearer {{secrets.hotel_api_key}}"
    }
  }
}

Security Best Practices:

  • Never hardcode API keys in tool descriptors
  • Use separate keys for staging and production
  • Rotate keys regularly
  • Store secrets encrypted in database
  • Limit secret access to server-side code only

Deployment Checklist

Before going live, verify every configuration element:

  • Tenant configured with correct tenantId, name, and contacts
  • Agent settings point to correct prompt and tools (GitHub or database)
  • Widget key(s) created with exact origin URL(s)
  • Rate limits set appropriate for expected traffic
  • API secrets stored and referenced correctly in tools
  • Test widget embedded on staging site
  • Voice sessions tested end-to-end (search, book, confirm)
  • Error handling verified (API failures, no results, invalid inputs)
  • Monitoring enabled for session transcripts and usage
  • Escalation path defined for human-in-the-loop scenarios

Embedding the Widget

Once configured, embed the VOX widget on your site:

<!-- Add to your website's <head> or before closing </body> -->
<script>
  (function() {
    window.voxConfig = {
      tenantId: 'cypress-resorts',
      agentId: 'concierge',
      widgetKey: 'w_cypress_main_7f1b0e9c64f54d1a'
    };
    var script = document.createElement('script');
    script.src = 'https://vox.strategicmachines.ai/widget.js';
    script.async = true;
    document.head.appendChild(script);
  })();
</script>

The widget will:

  • Validate the key and origin
  • Display a voice interface button
  • Handle microphone permissions
  • Stream audio to/from VOX platform
  • Render UI components from tool responses
  • Record transcripts for monitoring

Monitoring and Maintenance

After deployment, actively monitor agent performance:

Key Metrics to Track:

  • Session volume (daily/weekly/monthly)
  • Concurrent session peaks
  • Conversation completion rate
  • Average session duration
  • Tool call success/failure rates
  • Escalation frequency
  • Customer satisfaction (if collecting feedback)

Operational Tasks:

  • Review conversation transcripts weekly
  • Refine prompts based on real user language
  • Add new tools as use cases emerge
  • Adjust rate limits based on growth
  • Rotate API secrets quarterly
  • Update agent configs for seasonal campaigns

Next Steps

Your agent is configured and ready for production. Explore real-world examples to see complete implementations: