type Voice = variant { ara; eve; leo; rex; sal; }; type UserRole = variant { admin; guest; user; }; type TwilioLineMutationResult = variant { err: text; ok: vec TwilioLine; }; type TwilioLineInput = record { enabled: bool; name: text; phoneNumber: text; }; type TwilioLine = record { enabled: bool; name: text; phoneNumber: text; }; type TurnDetection = record { prefixPaddingMs: nat; serverVad: bool; silenceDurationMs: nat; threshold: float64; }; type ToolsEnabled = record { functionCalling: bool; webSearch: bool; xSearch: bool; }; type TermsStatus = record { acceptedAt: opt int; acceptedVersion: opt text; current: bool; expiresAt: opt int; "text": text; version: text; }; type SystemLog = record { callId: opt nat; level: variant { error; info; warn; }; message: text; timestamp: int; }; type StripeMode = variant { live; test; }; type SampleRate = variant { hz16000; hz22050; hz24000; hz32000; hz44100; hz48000; hz8000; }; type ReserveCallResult = variant { err: text; ok: CallReservationPublic; }; type RequestCallEndResult = variant { err: text; ok: PendingCallEnd; }; type PurchaseIntentStatus = variant { canceled; paid; pending; }; type PurchaseIntentPublic = record { amountCents: nat; createdAt: int; id: text; mode: StripeMode; packageId: text; paidAt: opt int; seconds: nat; status: PurchaseIntentStatus; stripeSessionId: opt text; user: principal; }; type PresetId = nat; type PendingCallEnd = record { callId: opt nat; callSid: opt text; id: text; reason: text; requestedAt: int; reservationId: text; serverSessionId: opt text; }; type NonAdminPhoneTimeSummary = record { availableSeconds: nat; balanceSeconds: nat; reservedSeconds: nat; userCount: nat; }; type InitiateCallResult = variant { err: text; ok: record { callId: nat; callSid: text; }; }; type InitiateCallInput = record { presetId: nat; recipientPhone: text; }; type IcrcAccount = record { owner: principal; subaccount: opt blob; }; type IcpTransferStatus = variant { completed; failed; pending; }; type IcpTransferResult = variant { err: AgentError; ok: IcpTransfer; }; type IcpTransfer = record { amountE8s: nat; blockIndex: opt nat; createdAt: int; error: opt text; id: text; status: IcpTransferStatus; to: IcrcAccount; user: principal; }; type IcpPurchaseStatus = variant { completed; failed; pending; }; type IcpPurchaseResult = variant { err: AgentError; ok: IcpPurchase; }; type IcpPurchase = record { amountE8s: nat; blockIndex: opt nat; createdAt: int; error: opt text; id: text; packageId: text; seconds: nat; status: IcpPurchaseStatus; user: principal; }; type IcpPricingResult = variant { err: text; ok: IcpPricing; }; type IcpPricing = record { expiresAt: int; isFresh: bool; ledgerCanister: principal; packages: vec IcpPhoneTimePackage; refreshCostCycles: nat; sourceTimestampSeconds: nat64; tokenDecimals: nat8; tokenSymbol: text; updatedAt: int; usdRate: nat64; usdRateDecimals: nat32; }; type IcpPhoneTimePackage = record { amountCents: nat; id: text; name: text; priceE8s: nat; seconds: nat; }; type CreatePurchaseIntentResult = variant { err: text; ok: PurchaseIntentPublic; }; type CreateLinkOfferResult = variant { err: text; ok: record { accountPrincipal: principal; code: text; expiresAt: int; }; }; type ClaimLinkOfferResult = variant { err: text; ok: AccountIdentity; }; type CallStatus = variant { completed; failed; inProgress; pending; }; type CallReservationStatus = variant { active; canceled; finished; "reserved"; }; type CallReservationPublic = record { allowedSeconds: nat; billedSeconds: opt nat; callId: nat; callSid: opt text; callToken: opt text; canceledReason: opt text; createdAt: int; expiresAt: int; finishedAt: opt int; id: text; presetId: nat; recipientPhone: text; startedAt: opt int; status: CallReservationStatus; transcript: opt text; usedSeconds: opt nat; user: principal; }; type CallRecordPublic = record { callSid: opt text; endTime: opt int; id: nat; presetId: nat; recipientPhone: text; startTime: int; status: CallStatus; transcript: opt text; userId: principal; }; type CallPresetMutationResult = variant { err: text; ok: CallPreset; }; type CallPresetInput = record { audioFormat: AudioFormat; name: text; sampleRate: SampleRate; systemPrompt: text; toolsEnabled: ToolsEnabled; turnDetection: TurnDetection; voice: Voice; voiceId: opt text; }; type CallPreset = record { audioFormat: AudioFormat; id: nat; name: text; ownerId: principal; sampleRate: SampleRate; systemPrompt: text; toolsEnabled: ToolsEnabled; turnDetection: TurnDetection; voice: Voice; voiceId: opt text; }; type CallId = nat; type BillingStatus = record { availableSeconds: nat; balanceSeconds: nat; packages: vec BillingPackage; reservedSeconds: nat; }; type BillingPackage = record { amountCents: nat; id: text; name: text; seconds: nat; }; type BillingMutationResult = variant { err: text; ok: bool; }; type Backend = service { _initializeAccessControl: () -> (); adminAddPromoMinutes: (user: principal, minutes: nat) -> (BillingMutationResult); adminGetNonAdminPhoneTimeSummary: () -> (NonAdminPhoneTimeSummary) query; adminGetSystemLogs: (limit: nat) -> (vec SystemLog) query; adminListAllCalls: () -> (vec CallRecordPublic) query; adminListUserCalls: (userId: principal) -> (vec CallRecordPublic) query; adminSetIcpUsdRate: (rate: nat64, decimals: nat32, sourceTimestampSeconds: nat64) -> (IcpPricingResult); agentAcceptTerms: () -> (TermsStatus); agentCancelQueuedCall: (jobId: text) -> (bool); agentEndCall: (jobId: text) -> (AgentCallResult); agentGetAccountIdentity: () -> (AgentAccount) query; agentGetAccountStatus: () -> (AgentAccountStatusResult); agentGetCallArtifacts: (callId: nat) -> (opt AgentCallArtifacts) query; agentGetLiveCallLink: (jobId: text) -> (opt AgentLiveCallLink) query; agentGetTermsStatus: () -> (TermsStatus) query; agentInitialize: (displayName: text) -> (AgentInitializeResult); agentListCallJobs: () -> (vec AgentCallJob) query; agentPurchasePhoneTime: (packageId: text, idempotencyKey: text) -> (IcpPurchaseResult); agentQueueCall: (input: AgentCallInput) -> (AgentCallResult); agentRefreshIcpPricing: () -> (IcpPricingResult); agentTransferIcp: (to: IcrcAccount, amountE8s: nat, idempotencyKey: text) -> (IcpTransferResult); assignCallerUserRole: (user: principal, role: UserRole) -> (); cancelCallReservation: (reservationId: text, reason: text) -> (BillingMutationResult); cancelCallReservationByCallSidForServer: (callSid: text, reason: text) -> (BillingMutationResult); claimAccountLinkOffer: (code: text) -> (ClaimLinkOfferResult); claimAgentCallForServer: (jobId: text) -> (opt AgentCallDispatch); clearPendingCallEndForServer: (id: text) -> (bool); completeAgentCallDispatchForServer: (jobId: text, callSid: opt text, serverSessionId: opt text, liveAudioUrl: opt text) -> (bool); createAccountLinkOffer: () -> (CreateLinkOfferResult); createAnsweringPreset: (input: AnsweringPresetInput) -> (AnsweringPresetMutationResult); createPreset: (input: CallPresetInput) -> (CallPreset); createPurchaseIntent: (packageId: text) -> (CreatePurchaseIntentResult); creditPaidSeconds: (stripeSessionId: text, purchaseIntentId: text, user: principal, seconds: nat, mode: StripeMode) -> (BillingMutationResult); deleteAnsweringPreset: (id: PresetId) -> (bool); deletePreset: (id: PresetId) -> (bool); duplicatePreset: (id: PresetId) -> (opt CallPreset); extendCallReservationForServer: (reservationId: text) -> (ReserveCallResult); failAgentCallDispatchForServer: (jobId: text, errorMessage: text) -> (bool); finishAnsweringLiveSessionForServer: (sessionId: text) -> (bool); finishCallAndDebit: (reservationId: text, usedSeconds: nat, callSid: opt text, transcript: opt text) -> (BillingMutationResult); finishCallByCallSidForServer: (callSid: text, usedSeconds: nat, transcript: opt text) -> (BillingMutationResult); getAdminConfig: () -> (record { hasTwilioAuth: bool; hasXaiKey: bool; twilioAccountSid: text; twilioFromNumber: text; twilioPhoneNumbers: vec TwilioLine; }) query; getAgentGuide: () -> (AgentGuide) query; getAgentPricing: () -> (IcpPricing) query; getAnsweringPreset: (id: PresetId) -> (opt AnsweringPreset) query; getAnsweringPresetForServer: (webhookSecret: text, phoneNumber: text) -> (opt AnsweringPreset) query; getApiDoc: () -> (text) query; getBillingPackages: () -> (vec BillingPackage) query; getCallRecord: (id: CallId) -> (opt CallRecordPublic) query; getCallerUserRole: () -> (UserRole) query; getMyAccountIdentity: () -> (AccountIdentity) query; getMyBillingStatus: () -> (BillingStatus) query; getPreset: (id: PresetId) -> (opt CallPreset) query; getPresetForServer: (id: PresetId) -> (opt CallPreset) query; getPurchaseIntentForServer: (purchaseIntentId: text) -> (opt PurchaseIntentPublic) query; getTwilioLineNumbersForServer: () -> (vec text) query; initiateCall: (input: InitiateCallInput) -> (InitiateCallResult); isCallerAdmin: () -> (bool) query; listMyAnsweringLiveSessions: () -> (vec AnsweringLiveSession) query; listMyAnsweringPresets: () -> (vec AnsweringPreset) query; listMyCalls: () -> (vec CallRecordPublic) query; listMyPresets: () -> (vec CallPreset) query; listOpenCallReservationsForServer: (limit: nat) -> (vec CallReservationPublic) query; listPendingAgentCallsForServer: (limit: nat) -> (vec AgentCallJob) query; listPendingCallEndsForServer: (limit: nat) -> (vec PendingCallEnd) query; markReservationStarted: (reservationId: text, callSid: text) -> (BillingMutationResult); registerAnsweringLiveSessionForServer: (session: AnsweringLiveSession) -> (bool); removeTwilioLine: (phoneNumber: text) -> (TwilioLineMutationResult); requestEndActiveCall: (callId: CallId) -> (RequestCallEndResult); reserveCall: (input: InitiateCallInput) -> (ReserveCallResult); reserveIncomingAnsweringCall: (webhookSecret: text, callerPhone: text, twilioToNumber: text, callSid: text) -> (ReserveCallResult); setAdminConfig: (xaiApiKey: text, twilioAccountSid: text, twilioAuthToken: text, twilioFromNumber: text) -> (); setAnsweringPresetEnabled: (id: PresetId, enabled: bool) -> (AnsweringPresetMutationResult); setTwilioLine: (input: TwilioLineInput) -> (TwilioLineMutationResult); setTwilioLineEnabled: (phoneNumber: text, enabled: bool) -> (TwilioLineMutationResult); twilioWebhook: (callSid: text, callStatus: text) -> (text); updateAnsweringPreset: (id: PresetId, input: AnsweringPresetInput) -> (AnsweringPresetMutationResult); updateAnsweringPresetInstructions: (id: PresetId, systemPrompt: text) -> (AnsweringPresetMutationResult); updateCallStatus: (callId: CallId, status: CallStatus, transcript: opt text) -> (bool); updatePreset: (id: PresetId, input: CallPresetInput) -> (opt CallPreset); updatePresetInstructions: (id: PresetId, systemPrompt: text) -> (CallPresetMutationResult); verifyAnsweringPresetForServer: (webhookSecret: text, phoneNumber: text) -> (AnsweringPresetMutationResult); verifyCallReservation: (reservationId: text, callToken: text) -> (ReserveCallResult); }; type AudioFormat = variant { pcm; pcma; pcmu; }; type AnsweringPresetStatus = variant { pendingVerification; verified; }; type AnsweringPresetMutationResult = variant { err: text; ok: AnsweringPreset; }; type AnsweringPresetInput = record { audioFormat: AudioFormat; captureOptions: AnsweringCaptureOptions; enabled: bool; name: text; phoneNumber: text; sampleRate: SampleRate; systemPrompt: text; toolsEnabled: ToolsEnabled; turnDetection: TurnDetection; voice: Voice; voiceId: opt text; webhookSecret: text; }; type AnsweringPreset = record { audioFormat: AudioFormat; captureOptions: AnsweringCaptureOptions; createdAt: int; enabled: bool; id: nat; lastIncomingAt: opt int; name: text; ownerId: principal; phoneNumber: text; sampleRate: SampleRate; systemPrompt: text; toolsEnabled: ToolsEnabled; turnDetection: TurnDetection; updatedAt: int; verificationStatus: AnsweringPresetStatus; verifiedAt: opt int; voice: Voice; voiceId: opt text; webhookSecret: text; }; type AnsweringLiveSession = record { allowedSeconds: nat; answeringPresetId: nat; answeringPresetName: text; callSid: text; callerPhone: text; monitorToken: text; sessionId: text; startedAt: int; userId: principal; }; type AnsweringCaptureOptions = record { consentConfirmed: bool; recordAudio: bool; saveTranscript: bool; }; type AgentProfile = record { createdAt: int; displayName: text; "principal": principal; updatedAt: int; }; type AgentLiveCallLink = record { callId: nat; expiresAt: int; jobId: text; note: text; url: text; }; type AgentInitializeResult = variant { err: text; ok: AgentProfile; }; type AgentGuide = record { answeringWorkflow: vec text; apiVersion: text; appName: text; authentication: vec text; callWorkflow: vec text; capabilities: vec AgentCapability; firstActions: vec text; paymentWorkflow: vec text; pricing: IcpPricing; productionMcpUrl: text; requiredAnsweringInformation: vec text; requiredCallInformation: vec text; safetyAndConsent: vec text; summary: text; }; type AgentError = record { availablePhoneSeconds: nat; code: text; message: text; pricing: vec IcpPhoneTimePackage; retryable: bool; }; type AgentCapability = record { description: text; methodName: text; name: text; requiresUpdatePermission: bool; }; type AgentCallResult = variant { err: AgentError; ok: AgentCallJob; }; type AgentCallJobStatus = variant { canceled; claimed; dispatched; failed; queued; }; type AgentCallJob = record { callId: nat; callSid: opt text; captureOptions: AgentCallCaptureOptions; claimedAt: opt int; createdAt: int; error: opt text; expiresAt: int; id: text; liveAudioNote: opt text; liveAudioUrl: opt text; presetId: nat; recipientPhone: text; reservationId: text; serverSessionId: opt text; status: AgentCallJobStatus; user: principal; }; type AgentCallInput = record { captureOptions: AgentCallCaptureOptions; idempotencyKey: text; presetId: nat; recipientPhone: text; }; type AgentCallDispatch = record { callToken: text; job: AgentCallJob; }; type AgentCallCaptureOptions = record { consentConfirmed: bool; recordAudio: bool; saveTranscript: bool; }; type AgentCallArtifacts = record { audioMimeType: opt text; audioUrl: opt text; call: CallRecordPublic; note: text; transcript: opt text; }; type AgentAccountStatusResult = variant { err: text; ok: AgentAccountStatus; }; type AgentAccountStatus = record { account: AgentAccount; billing: BillingStatus; icpBalanceE8s: nat; ledgerFeeE8s: nat; lowPhoneTime: bool; message: text; pricing: IcpPricing; }; type AgentAccount = record { depositAccount: IcrcAccount; ledgerCanister: principal; legacyAccountId: blob; legacyAccountIdHex: text; "principal": principal; }; type AccountIdentity = record { accountPrincipal: principal; groupPrincipals: vec principal; isLinked: bool; sessionPrincipal: principal; }; service : () -> Backend