For all new projects, use agents to create calls. This approach provides consistency, reusability, and easier maintenance.

Basic Agent Call

Start a call using an existing agent and pass in any template variables:
Example: Create a New Agent Call
const startAgentCall = async (agentId) => {
  const response = await fetch(`https://api.ultravox.ai/api/agents/${agentId}/calls`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': 'your-api-key'
    },
    body: JSON.stringify({
      templateContext: {
        customerName: "Jane Smith",
        accountType: "Premium"
      }
    })
  });
  
  return await response.json();
};

Template Context and Variables

Provide dynamic data to your agent at call creation time:
Example: Template Context Variables
{
  templateContext: {
    customerName: "John Doe",
    accountType: "enterprise",
    lastInteraction: "2025-05-15",
    accountBalance: "$1,250.00"
  }
}

Overriding Agent Settings

When starting a call with an agent, you can override specific settings from the agent’s call template. Here are the parameters you can include in the request body:
ParameterDescriptionTypeExample
templateContextVariables for template substitutionObject{ customerName: "John" }
initialMessagesConversation history to start fromArrayPrevious chat context
metadataKey-value pairs for trackingObject{ source: "website" }
mediumCommunication protocolObject{ twilio: {} }.
joinTimeoutTime limit for user to joinString"60s"
maxDurationMaximum call lengthString"1800s"
recordingEnabled.Whether to record audioBooleantrue / false
initialOutputMediumStart with voice or textString"voice" / "text"
firstSpeakerSettingsInitial conversation behaviorObject{ agent: { text: "..." } }
experimentalSettingsExperimental settings for the callObjectVaries
Example of overriding agent settings when creating a call:
Example: Overriding Agent Settings
const response = await fetch(`https://api.ultravox.ai/api/agents/${agentId}/calls`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'your-api-key'
  },
  body: JSON.stringify({
    // Template context
    templateContext: {
      customerName: "VIP Customer",
      accountType: "enterprise"
    },
    
    // Override agent settings for this specific call
    maxDuration: "900s", // 15 minutes instead of default
    recordingEnabled: false  // Disable call recording
  })
});

Direct Call Alternative

For legacy integration, testing, or very simple use cases, you can create calls directly without agents:
const startDirectCall = async () => {
  const response = await fetch('https://api.ultravox.ai/api/calls', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': 'your-api-key'
    },
    body: JSON.stringify({
      systemPrompt: "You are a helpful customer service agent. Be friendly and professional.",
      voice: "Jessica",
      temperature: 0.3,
      model: "fixie-ai/ultravox",
      joinTimeout: "30s",
      maxDuration: "3600s",
      recordingEnabled: false,
      
      firstSpeakerSettings: {
        agent: {
          text: "Hello! How can I help you today?"
        }
      },
      
      selectedTools: [
        { toolName: 'knowledgebaseLookup' },
        { toolName: 'transferToHuman' }
      ],
      
      metadata: {
        purpose: "customer_support",
        test: "true"
      }
    })
  });
  
  return await response.json();
};

Prior Call Inheritance

You can reuse the same properties (including message history) from a prior call by passing in a query param:
Example: Using Prior Call ID
const continueFromPriorCall = async (priorCallId) => {
  const response = await fetch(`https://api.ultravox.ai/api/calls?priorCallId=${priorCallId}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': 'your-api-key'
    },
    body: JSON.stringify({
      // Only override what you need to change
      systemPrompt: "Continue the previous conversation with updated context...",
      metadata: {
        continuation: "true",
        originalCall: priorCallId
      }
    })
  });
  
  return await response.json();
};
When using priorCallId, the new call inherits all properties from the prior call unless explicitly overridden. The prior call’s message history becomes the new call’s initialMessages.

Next Steps