ShopCall.ai integrates with VAPI (Voice AI Platform) to receive and store call data from AI-powered phone conversations. This integration allows the system to track call logs, transcripts, recordings, and analytics from VAPI calls.
VAPI Webhook Endpoint (/functions/v1/vapi-webhook)
Database Schema (call_logs table)
API Endpoint (/api/call-logs)
WebUI (/call-logs page)
call_logs Table| Field | Type | Description |
|---|---|---|
vapi_call_id |
TEXT | Unique identifier from VAPI for this call |
messages |
JSONB | Array of conversation messages (bot/user/system/tool_calls) |
analysis |
JSONB | VAPI analysis object (summary, successEvaluation) |
stereo_recording_url |
TEXT | URL to stereo recording from VAPI |
pcap_url |
TEXT | URL to SIP packet capture file |
log_url |
TEXT | URL to VAPI call logs |
vapi_timestamp |
BIGINT | VAPI event timestamp in milliseconds |
idx_call_logs_vapi_call_id - Fast lookups by VAPI call IDidx_call_logs_vapi_timestamp - Time-based querieshttps://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/vapi-webhook
The integration listens for end-of-call-report events from VAPI.
{
"message": {
"timestamp": 1763633517714,
"type": "end-of-call-report",
"analysis": {
"summary": "Call summary text",
"successEvaluation": "true"
},
"artifact": {
"messages": [
{
"role": "bot|user|system|tool_calls|tool_call_result",
"message": "Message text",
"time": 1763633305414,
"endTime": 1763633327672,
"secondsFromStart": 0.486,
"duration": 270
}
],
"transcript": "Full conversation transcript",
"recordingUrl": "https://storage.vapi.ai/...",
"stereoRecordingUrl": "https://storage.vapi.ai/...",
"pcapUrl": "https://storage.vapi.ai/...",
"logUrl": "https://calllogs.vapi.ai/..."
},
"call": {
"id": "unique-call-id",
"assistantId": "assistant-id",
"phoneNumberId": "phone-number-id",
"customerId": "customer-phone-number",
"costBreakdown": {
"stt": 0.0012,
"llm": 0.0034,
"tts": 0.0023,
"twilio": 0.0050,
"total": 0.0119
}
}
}
}
| VAPI Field | call_logs Field |
|---|---|
message.call.id |
vapi_call_id |
message.timestamp |
vapi_timestamp, started_at, ended_at |
message.artifact.messages |
messages |
message.analysis |
analysis |
message.analysis.summary |
summary |
message.artifact.transcript |
transcript |
message.artifact.recordingUrl |
recording_url |
message.artifact.stereoRecordingUrl |
stereo_recording_url |
message.artifact.pcapUrl |
pcap_url |
message.artifact.logUrl |
log_url |
message.call.assistantId |
assistant_id |
message.call.phoneNumberId |
phone_number_id |
message.call.customerId |
customer_number |
message.call.costBreakdown.* |
cost_stt, cost_llm, cost_tts, cost_twilio, cost_total |
analysis.successEvaluation = "true" → call_outcome = "resolved"analysis.successEvaluation = "false" → call_outcome = "not_interested"call_outcome = "pending"Duration is calculated from the last message's secondsFromStart field.
Displays:
Shows:
Purpose: Receive VAPI webhooks
Authentication: None (service-level endpoint)
Request Body: VAPI webhook payload (JSON)
Response:
{
"status": "success",
"call_log_id": "uuid",
"message": "Call log stored successfully"
}
Purpose: Retrieve call logs for authenticated user
Authentication: Bearer token (required)
Response:
{
"success": true,
"call_logs": [
{
"id": "uuid",
"time": "2025-11-20 10:30:45",
"customer": "...xxx-1234",
"intent": "Customer inquiry",
"outcome": "resolved",
"duration": "3:25",
"sentiment": "Positive",
"cost": "$0.0119",
"outcomeColor": "text-green-500",
"sentimentColor": "text-green-500",
"fullData": { /* complete call log object */ }
}
]
}
Currently, the webhook endpoint accepts all POST requests. For production, consider:
...xxx-1234)# Migration is already applied
# File: /supabase/migrations/20251120_vapi_integration.sql
# Deploy VAPI webhook handler
supabase functions deploy vapi-webhook --project-ref ztklqodcdjeqpsvhlpud
# Deploy updated API endpoint
supabase functions deploy api --project-ref ztklqodcdjeqpsvhlpud
Required in Supabase Edge Functions:
SUPABASE_URL - Supabase project URLSUPABASE_SERVICE_ROLE_KEY - Service role key for database accessTest Webhook Endpoint:
curl -X POST https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/vapi-webhook \
-H "Content-Type: application/json" \
-d @test-payload.json
Test API Endpoint:
curl https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/api/call-logs \
-H "Authorization: Bearer YOUR_TOKEN"
Test WebUI:
/call-logsSee message object in the VAPI webhook payload example above.
Webhook not receiving data
end-of-call-report event is enabledCall logs not appearing in UI
Missing transcript or messages
artifact.messages array existsView Edge Function logs:
# Via Supabase Dashboard
https://supabase.com/dashboard/project/ztklqodcdjeqpsvhlpud/functions
# Via CLI
supabase functions logs vapi-webhook