Structured outputs quickstart

Get started with structured data extraction in 5 minutes

Overview

This quickstart guide will help you set up structured outputs to automatically extract customer information from phone calls. In just a few minutes, you’ll create a structured output, link it to an assistant, and test data extraction.

What are structured outputs?

Structured outputs are AI-powered data extraction templates that automatically capture and organize information from conversations. They work by:

  1. Listening to conversations - As your assistant talks with customers, structured outputs analyze the conversation in real-time
  2. Extracting key information - Based on your defined schema, they identify and extract relevant data points like names, emails, preferences, and issues
  3. Validating and formatting - The extracted data is validated against your schema rules and formatted into clean, structured JSON
  4. Delivering results - The structured data is available immediately after the call ends via API or webhooks

When are structured outputs generated?

Structured outputs are processed:

  • During the call - Data is extracted in real-time as the conversation happens
  • After call completion - Final validation and formatting occurs when the call ends
  • Available via - Call artifacts in the API response or webhook events

Why use structured outputs?

  • Automate data entry - No more manual transcription or form filling
  • Ensure consistency - Every call captures the same structured information
  • Enable integrations - Automatically sync data to CRMs, ticketing systems, or databases
  • Improve analytics - Structured data is easier to analyze and report on

What you’ll build

A customer support assistant that automatically extracts:

  • Customer name and contact details
  • Issue description and priority
  • Requested follow-up actions

Prerequisites

Vapi account
API key

Get your API key from the Dashboard settings

Step 1: Create your structured output

You can create structured outputs using either the Dashboard UI or the API.

2

Configure Basic Settings

  1. Name: Enter “Support Ticket”
  2. Type: Select “AI” (for automatic extraction)
  3. Description: Add “Extract support ticket information from customer calls”
3

Define Your Schema

Use the visual schema builder or paste this JSON directly:

1{
2 "type": "object",
3 "properties": {
4 "customer": {
5 "type": "object",
6 "properties": {
7 "name": {"type": "string", "description": "Customer full name"},
8 "email": {"type": "string", "format": "email", "description": "Customer email"},
9 "phone": {"type": "string", "description": "Customer phone number"}
10 },
11 "required": ["name"]
12 },
13 "issue": {
14 "type": "object",
15 "properties": {
16 "description": {"type": "string", "description": "Issue description"},
17 "category": {
18 "type": "string",
19 "enum": ["billing", "technical", "general", "complaint"],
20 "description": "Issue category"
21 },
22 "priority": {
23 "type": "string",
24 "enum": ["low", "medium", "high", "urgent"],
25 "description": "Priority level"
26 }
27 },
28 "required": ["description", "category"]
29 }
30 },
31 "required": ["customer", "issue"]
32}
4

Save and Copy ID

  1. Click Create Structured Output
  2. Copy the generated ID from the details page
  3. You’ll use this ID to link to your assistant

Option B: Using the API

Define what information you want to extract using a JSON Schema. JSON Schema is a standard for describing data structures - learn more about JSON Schema here.

$curl -X POST https://api.vapi.ai/structured-output \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "name": "Support Ticket",
> "type": "ai",
> "description": "Extract support ticket information from customer calls",
> "schema": {
> "type": "object",
> "properties": {
> "customer": {
> "type": "object",
> "properties": {
> "name": {
> "type": "string",
> "description": "Customer full name"
> },
> "email": {
> "type": "string",
> "format": "email",
> "description": "Customer email address"
> },
> "phone": {
> "type": "string",
> "description": "Customer phone number"
> }
> },
> "required": ["name"]
> },
> "issue": {
> "type": "object",
> "properties": {
> "description": {
> "type": "string",
> "description": "Description of the customer issue"
> },
> "category": {
> "type": "string",
> "enum": ["billing", "technical", "general", "complaint"],
> "description": "Issue category"
> },
> "priority": {
> "type": "string",
> "enum": ["low", "medium", "high", "urgent"],
> "description": "Issue priority level"
> }
> },
> "required": ["description", "category"]
> },
> "followUp": {
> "type": "object",
> "properties": {
> "required": {
> "type": "boolean",
> "description": "Whether follow-up is needed"
> },
> "method": {
> "type": "string",
> "enum": ["email", "phone", "none"],
> "description": "Preferred follow-up method"
> },
> "notes": {
> "type": "string",
> "description": "Additional notes for follow-up"
> }
> }
> }
> },
> "required": ["customer", "issue"]
> }
> }'

Save the returned id from the response - you’ll need it to link to your assistant.

Step 2: Create an assistant with structured outputs

Now create an assistant that uses your structured output:

$curl -X POST https://api.vapi.ai/assistant \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "name": "Customer Support Agent",
> "firstMessage": "Hello! I'\''m here to help you with your support request. Can you please tell me your name and describe the issue you'\''re experiencing?",
> "model": {
> "provider": "openai",
> "model": "gpt-4-turbo-preview",
> "messages": [
> {
> "role": "system",
> "content": "You are a helpful customer support agent. Gather the customer'\''s information and understand their issue. Be empathetic and professional."
> }
> ]
> },
> "voice": {
> "provider": "vapi",
> "voiceId": "jennifer"
> },
> "artifactPlan": {
> "structuredOutputIds": ["YOUR_STRUCTURED_OUTPUT_ID_HERE"]
> }
> }'

Step 3: Test with a phone call

Make a test call to your assistant:

$curl -X POST https://api.vapi.ai/call \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "assistantId": "YOUR_ASSISTANT_ID_HERE",
> "customer": {
> "number": "+1234567890"
> }
> }'

During the call, try saying something like: “Hi, my name is John Smith. My email is john@example.com. I’m having trouble logging into my account - it keeps showing an error message. This is pretty urgent for me.”

Step 4: Retrieve extracted data

After the call ends, retrieve the extracted information:

$curl -X GET "https://api.vapi.ai/call/YOUR_CALL_ID_HERE" \
> -H "Authorization: Bearer $VAPI_API_KEY"

Expected output

You should see extracted data like this:

1{
2 "customer": {
3 "name": "John Smith",
4 "email": "john@example.com",
5 "phone": "+1234567890"
6 },
7 "issue": {
8 "description": "Unable to login to account, receiving error message",
9 "category": "technical",
10 "priority": "urgent"
11 },
12 "followUp": {
13 "required": true,
14 "method": "email",
15 "notes": "Customer needs immediate assistance with login issue"
16 }
17}

Step 5: Set up webhook (optional)

To automatically receive extracted data when calls end, set up a webhook:

1const express = require('express');
2const app = express();
3
4app.use(express.json());
5
6app.post('/vapi/webhook', (req, res) => {
7 const { type, call } = req.body;
8
9 if (type === 'call.ended') {
10 const outputs = call.artifact?.structuredOutputs;
11
12 if (outputs) {
13 Object.entries(outputs).forEach(([outputId, data]) => {
14 if (data.result) {
15 // Process the extracted support ticket
16 console.log('New support ticket:', data.result);
17
18 // Example: Create ticket in your system
19 createSupportTicket({
20 customer: data.result.customer,
21 issue: data.result.issue,
22 priority: data.result.issue.priority,
23 followUp: data.result.followUp
24 });
25 }
26 });
27 }
28 }
29
30 res.status(200).send('OK');
31});
32
33function createSupportTicket(ticketData) {
34 // Your ticket creation logic here
35 console.log('Creating ticket in system:', ticketData);
36}
37
38app.listen(3000, () => {
39 console.log('Webhook server running on port 3000');
40});

Then update your assistant with the webhook URL:

$curl -X PATCH "https://api.vapi.ai/assistant/YOUR_ASSISTANT_ID" \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "server": {
> "url": "https://your-domain.com/vapi/webhook"
> }
> }'

Next steps

Common patterns

Multiple extractions

You can attach multiple structured outputs to extract different types of data:

1{
2 artifactPlan: {
3 structuredOutputIds: [
4 "550e8400-e29b-41d4-a716-446655440001", // Customer details extraction
5 "550e8400-e29b-41d4-a716-446655440002", // Appointment requests extraction
6 "550e8400-e29b-41d4-a716-446655440003" // Satisfaction feedback extraction
7 ]
8 }
9}
The structuredOutputIds are UUIDs returned when you create each structured output configuration.

Conditional extraction

Use conditional logic in your schema to handle different scenarios:

1{
2 "if": {
3 "properties": {
4 "requestType": {"const": "appointment"}
5 }
6 },
7 "then": {
8 "required": ["preferredDate", "preferredTime"]
9 }
10}

Validation patterns

Common validation patterns for reliable extraction:

1{
2 "email": {
3 "type": "string",
4 "format": "email",
5 "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
6 },
7 "phone": {
8 "type": "string",
9 "pattern": "^\\+?[1-9]\\d{1,14}$"
10 },
11 "zipCode": {
12 "type": "string",
13 "pattern": "^\\d{5}(-\\d{4})?$"
14 }
15}

Tips for success

Best practices for reliable extraction:

  • Start with required fields only for critical data
  • Use enums for categorical data to ensure consistency
  • Add descriptions to help the AI understand context
  • Test with real conversations before production use
  • Monitor extraction success rates and iterate on schemas

Troubleshooting

IssueSolution
No data extractedVerify the information was mentioned in the call and check schema validity
Partial extractionMake non-critical fields optional and simplify nested structures
Incorrect valuesAdd more specific validation patterns and field descriptions
Extraction failsCheck API logs, verify assistant configuration, and test with simpler schema

Get help

Need assistance? We’re here to help: