Skip to main content

Call Tables

calls

Individual call records with transcripts, AI analysis, and metadata. Records are created from webhook events or historical sync jobs.

ColumnTypeDefaultNullableDescription
iduuiduuid_generate_v4()noPrimary key
agency_iduuidnoFK → agencies.id
client_iduuidyesFK → clients.id
campaign_iduuidyesFK → campaigns.id
ultravox_call_idvarchar(255)noUltravox-side call identifier
ultravox_agent_idvarchar(255)yesAgent that handled the call
ultravox_agent_namevarchar(255)yesAgent display name at time of call
sourcecall_source'webhook'noHow the record was created
sync_job_iduuidyesFK → historical_sync_jobs.id (if imported)
directioncall_directionyesInbound or outbound
from_numbervarchar(50)yesCaller phone number
to_numbervarchar(50)yesCalled phone number
created_attimestamptznoWhen the call started (from Ultravox)
joined_attimestamptzyesWhen the agent joined
ended_attimestamptzyesWhen the call ended
duration_secondsintegeryesCall duration
end_reasonvarchar(50)yesWhy the call ended (e.g., hangup, timeout)
short_summarytextyesOne-line call summary
summarytextyesDetailed call summary
metadatajsonb'{}'yesAdditional call metadata
transcriptjsonbyesFull call transcript
transcript_statustranscript_status'pending'noTranscript fetch state
transcript_errortextyesTranscript fetch error message
transcript_fetched_attimestamptzyesWhen transcript was fetched
analysisjsonbyesAI analysis results
analysis_statusanalysis_status'pending'noAnalysis processing state
analysis_errortextyesAnalysis error message
analysis_completed_attimestamptzyesWhen analysis completed
raw_payloadjsonbyesOriginal webhook/API payload
has_recordingbooleanfalseyesWhether a recording exists
record_created_attimestamptznow()noWhen the DB record was created
record_updated_attimestamptznow()noLast DB record update (auto-updated)

Constraints:

ConstraintTypeDetails
calls_pkeyPrimary keyid
calls_ultravox_unique_per_agencyUnique(agency_id, ultravox_call_id)
calls_agency_id_fkeyForeign keyagency_idagencies(id) ON DELETE CASCADE
calls_client_id_fkeyForeign keyclient_idclients(id) ON DELETE SET NULL
calls_campaign_id_fkeyForeign keycampaign_idcampaigns(id) ON DELETE SET NULL
calls_duration_positiveCheckduration_seconds IS NULL OR duration_seconds >= 0

Indexes:

IndexColumnsNotes
idx_calls_agency_idagency_id
idx_calls_client_idclient_id
idx_calls_campaign_idcampaign_id
idx_calls_ultravox_call_idultravox_call_idLookup by Ultravox ID
idx_calls_ultravox_agent_idultravox_agent_idCalls by agent
idx_calls_created_atcreated_at DESCChronological listing
idx_calls_ended_atended_at DESCRecent ended calls
idx_calls_directiondirection
idx_calls_end_reasonend_reason
idx_calls_agency_created(agency_id, created_at DESC)Agency call history
idx_calls_client_created(client_id, created_at DESC)Client call history
idx_calls_campaign_created(campaign_id, created_at DESC)Campaign call history
idx_calls_transcript_statustranscript_statusFiltered: WHERE status IN ('pending', 'fetching')
idx_calls_analysis_statusanalysis_statusFiltered: WHERE status IN ('pending', 'processing')
idx_calls_sync_jobsync_job_idFiltered: WHERE sync_job_id IS NOT NULL

Triggers:

TriggerEventFunctionDescription
call_ended_queue_transcriptAFTER INSERT or UPDATEtrigger_call_ended_queue_transcript()Queues transcript fetch when a call ends
transcript_fetched_queue_analysisAFTER UPDATEtrigger_transcript_fetched_queue_analysis()Queues AI analysis when transcript is ready
update_calls_record_updated_atBEFORE UPDATEupdate_call_record_updated_at()Keeps record_updated_at current

Related edge functions: process-webhook-queue, process-enrichment-queue, get-call-recording


call_stats_daily

Aggregated daily call statistics per agency, optionally broken down by client and campaign. Populated by the refresh-aggregations edge function.

ColumnTypeDefaultNullableDescription
iduuiduuid_generate_v4()noPrimary key
agency_iduuidnoFK → agencies.id
client_iduuidyesFK → clients.id
campaign_iduuidyesFK → campaigns.id
stat_datedatenoThe date these stats cover
total_callsinteger0noTotal calls on this date
completed_callsinteger0noSuccessfully completed calls
failed_callsinteger0noFailed calls
total_duration_secondsbigint0noSum of all call durations
avg_duration_secondsnumeric(10,2)yesAverage call duration
min_duration_secondsintegeryesShortest call
max_duration_secondsintegeryesLongest call
inbound_callsinteger0noInbound call count
outbound_callsinteger0noOutbound call count
positive_sentiment_callsinteger0noCalls with positive sentiment
neutral_sentiment_callsinteger0noCalls with neutral sentiment
negative_sentiment_callsinteger0noCalls with negative sentiment
meetings_bookedinteger0noMeetings booked (SDR campaigns)
qualified_leadsinteger0noQualified leads (SDR campaigns)
objections_encounteredinteger0noObjections encountered (SDR campaigns)
issues_resolvedinteger0noIssues resolved (CS campaigns)
escalationsinteger0noEscalations (CS campaigns)
created_attimestamptznow()noRecord creation timestamp
updated_attimestamptznow()noLast update timestamp (auto-updated)

Constraints:

ConstraintTypeDetails
call_stats_daily_pkeyPrimary keyid
call_stats_daily_uniqueUnique(agency_id, client_id, campaign_id, stat_date)
call_stats_daily_agency_id_fkeyForeign keyagency_idagencies(id) ON DELETE CASCADE
call_stats_daily_client_id_fkeyForeign keyclient_idclients(id) ON DELETE CASCADE
call_stats_daily_campaign_id_fkeyForeign keycampaign_idcampaigns(id) ON DELETE CASCADE
call_stats_daily_counts_positiveCheckAll count and duration fields ≥ 0

Indexes:

IndexColumnsNotes
idx_call_stats_daily_agency(agency_id, stat_date DESC)Agency dashboard queries
idx_call_stats_daily_client(client_id, stat_date DESC)Client-filtered queries
idx_call_stats_daily_campaign(campaign_id, stat_date DESC)Campaign-filtered queries
idx_call_stats_daily_datestat_date DESCGlobal date queries
idx_call_stats_daily_agency_date_range(agency_id, stat_date)Date range queries

Triggers:

TriggerEventFunction
update_call_stats_daily_updated_atBEFORE UPDATEupdate_updated_at_column()

Related edge functions: refresh-aggregations


call_batches

Outbound batch call operations. Tracks progress of batch calls against a set of campaign contacts.

ColumnTypeDefaultNullableDescription
iduuiduuid_generate_v4()noPrimary key
agency_iduuidnoFK → agencies.id
campaign_iduuidyesFK → campaigns.id
agent_mapping_iduuidnoFK → agent_mappings.id
from_numbervarchar(20)noOriginating phone number (E.164)
statusbatch_status'pending'noCurrent batch status
modebatch_mode'immediate'noExecution mode
max_concurrentinteger10noMax simultaneous calls (1–100)
calls_per_minuteinteger30noRate limit (1–60)
total_contactsintegernoTotal contacts in batch
queuedinteger0noContacts queued for calling
in_progressinteger0noContacts currently being called
completedinteger0noContacts completed
failedinteger0noContacts failed
skippedinteger0noContacts skipped
scheduled_fortimestamptzyesWhen to start (for scheduled mode)
started_attimestamptzyesWhen processing began
completed_attimestamptzyesWhen processing finished
paused_attimestamptzyesWhen paused
telephony_batch_idvarchar(255)yesExternal telephony batch ID
error_messagetextyesLast error message
last_error_attimestamptzyesWhen the last error occurred
created_attimestamptznow()noRecord creation timestamp
updated_attimestamptznow()noLast update timestamp (auto-updated)

Constraints:

ConstraintTypeDetails
call_batches_pkeyPrimary keyid
call_batches_agency_id_fkeyForeign keyagency_idagencies(id) ON DELETE CASCADE
call_batches_agent_mapping_id_fkeyForeign keyagent_mapping_idagent_mappings(id) ON DELETE RESTRICT
call_batches_campaign_id_fkeyForeign keycampaign_idcampaigns(id) ON DELETE SET NULL
call_batches_from_number_formatCheckfrom_number ~ '^\+[1-9][0-9]{6,14}$'
call_batches_max_concurrent_rangeCheckmax_concurrent >= 1 AND max_concurrent <= 100
call_batches_calls_per_minute_rangeCheckcalls_per_minute >= 1 AND calls_per_minute <= 60
call_batches_counts_positiveCheckAll count fields ≥ 0

Indexes:

IndexColumnsNotes
idx_call_batches_agency_idagency_id
idx_call_batches_campaign_idcampaign_idFiltered: WHERE campaign_id IS NOT NULL
idx_call_batches_statusstatus
idx_call_batches_active(agency_id, status)Filtered: WHERE status IN ('pending', 'scheduled', 'processing', 'paused')
idx_call_batches_scheduledscheduled_forFiltered: WHERE status = 'scheduled' AND scheduled_for IS NOT NULL
idx_call_batches_telephony_idtelephony_batch_idFiltered: WHERE telephony_batch_id IS NOT NULL

Triggers:

TriggerEventFunction
update_call_batches_updated_atBEFORE UPDATEupdate_updated_at_column()

Views: v_call_batch_summary joins this table with agent_mappings and campaigns to include agent name, campaign name, and computed progress.