• Skip to main content
  • Skip to navigation
  • Skip to search
    Petunia™
    FeaturesPricingIntegrationsAboutContact
    Log inStart free trialSign up
    Loading
    Petunia™

    Reimagining customer communication for the modern business.

    Product

    • Features
    • Pricing
    • Integrations
    • Roadmap
    • What's New

    Resources

    • Help Center
    • Documentation
    • Guides
    • API Reference
    • Community
    • Support

    Company

    • About Us
    • Careers
    • Blog
    • Press
    • Contact

    © 2026 Gray Group International LLC. All rights reserved.·
    Made by gardenpatch 🌱

    Privacy PolicyTerms of ServiceCookie Policy

    Petunia™ is a trademark of Gray Group International LLC. The Petunia name, brand, product design, and content are proprietary. Unauthorized use, imitation, or copying is prohibited.

    Documentation

    CLIENT_INTEGRATIONS

    docs/features/CLIENT_INTEGRATIONS.md
    Docs homeGuidesSupport
    Quick links
    Start here
    How the docs are organized.
    Environment setup
    Configure env + run locally.
    Unified Inbox
    Inbox concepts & behavior.
    Voice AI setup
    Providers, Twilio, testing.
    Pricing model
    Source-of-truth pricing.
    Operations runbook
    How to operate safely.

    Client Integration Checklist

    This checklist explains which communications providers ship with Petunia by default and where customers must bring their own API keys (BYOK), phone numbers, or webhooks. Share it with every new portal so we never mix environments or leak credentials between tenants.

    Pricing Model

    Regardless of which keys a client uses, they always pay:

    • Subscription fee - Monthly/annual platform access
    • Commissions - Lead fees, booking fees, closure fees (performance-based)
    • Overages - Usage beyond tier allowances

    When using platform keys, clients also pay a 1% margin on API costs. BYOK clients avoid this margin but still pay subscription and commissions.

    Voice + AI Providers

    CapabilityDefault BehaviourBYOK OptionsImplementation Status
    Cartesia VoicePetunia supplies a shared platform key. Enabled automatically.Override via ClientApiKey (provider = 'cartesia').✅ ApiKeyResolver with client priority
    ElevenLabs VoiceDisabled by default. BYOK only.ELEVENLABS_API_KEY via encrypted ClientApiKey.✅ ApiKeyResolver with client priority
    Retell VoiceOptional add-on. BYOK only.RETELL_API_KEY via ClientApiKey.✅ ApiKeyResolver with client priority
    Anthropic AIPlatform key provided.Override via ClientApiKey (provider = 'anthropic').✅ ApiKeyResolver with client priority
    OpenAIPlatform key provided.Override via ClientApiKey (provider = 'openai').✅ ApiKeyResolver with client priority

    Telephony & Messaging Providers

    ProviderPhone NumbersAPI KeysImplementation Status
    TwilioCustomer-owned recommended. Platform can provision via API.Platform fallback + client override via ClientApiKey.✅ ApiKeyResolver + Phone Provisioning API
    SendGridN/A (email)Platform fallback + client override via ClientApiKey.✅ ApiKeyResolver with client priority
    RingCentralAlways customer-owned via OAuth.Customer OAuth credentials stored in Connection table.✅ OAuth connect flow at /api/connections/ringcentral

    Social & Integration Providers

    ProviderOAuth FlowImplementation Status
    Google BusinessCustomer connects via OAuth✅ /api/connections/google
    Facebook/MetaCustomer connects via OAuth✅ /api/connections/facebook
    InstagramCustomer connects via OAuth✅ /api/integrations/instagram/connect
    YelpCustomer connects via OAuth✅ /api/connections/yelp
    LinkedInCustomer connects via OAuth✅ /api/integrations/linkedin/connect
    Twitter/XCustomer connects via OAuth✅ /api/integrations/twitter/connect
    SlackCustomer connects via OAuth✅ /api/connections/slack
    WhatsAppCustomer connects via connection setup✅ /api/connections/whatsapp
    Stripe ConnectCustomer connects via OAuth✅ /api/integrations/stripe-connect

    Phone Number Provisioning

    Petunia can provision phone numbers for customers via Twilio:

    API Endpoint: POST /api/twilio/phone-numbers

    // Search for available numbers
    GET /api/twilio/phone-numbers?action=search&country=US&areaCode=415
    
    // Provision a number
    POST /api/twilio/phone-numbers
    {
      "phoneNumber": "+14155551234",
      "portalId": "portal_xxx",
      "friendlyName": "Main Line"
    }
    
    // List owned numbers
    GET /api/twilio/phone-numbers?action=list
    
    // Release a number (platform admin only)
    DELETE /api/twilio/phone-numbers?sid=PNxxx
    

    Numbers are automatically mapped to portals via PhoneNumberMapping table.

    Key Resolution Flow

    1. Request comes in for provider (e.g., 'twilio')
    2. ApiKeyResolver.resolveKey('twilio', clientId)
    3. Check ClientApiKey table for client-specific key
       → If found: use client key (source: 'client', no margin)
       → If not: fall back to platform env var (source: 'platform', 1% margin)
    4. Track usage via PlatformUsageTracker
    

    Where to Configure Keys

    TypeLocationWho ManagesWhen Used
    Platform defaults.env / VercelPetunia teamDemos, fallbacks
    Client API keysClientApiKey tableClient via Admin UIProduction BYOK
    OAuth credentialsConnection tableSystem via OAuth flowSocial integrations
    Phone mappingsPhoneNumberMapping tableAdmin via APIRouting calls/SMS

    Billing Integration

    Usage is tracked automatically by PlatformUsageTracker:

    • SMS: $0.0075/message (Twilio pricing)
    • Email: $0.0001/email (SendGrid pricing)
    • Voice: $0.05-0.10/minute (varies by provider)
    • AI: Token-based (Anthropic/OpenAI pricing)

    Billing includes:

    • Subscription fees (via Stripe subscription)
    • Usage overages (reported as Stripe invoice items)
    • Commission fees (leads, bookings, closures)
    • 1% API margin on platform key usage

    Implementation Checklist

    For new portal onboarding:

    • Verify subscription tier and set quotas
    • Configure voice provider (Cartesia default, or BYOK)
    • Set up phone number (provision via API or use existing)
    • Connect social accounts (Google, Facebook, Yelp)
    • Verify webhook endpoints are receiving events
    • Test SMS/Voice flows end-to-end
    • Confirm billing is tracking correctly

    Yelp Integration Runbook

    Overview

    • Production tenants ingest Yelp reviews via a durable Prisma-backed queue (YelpReviewSyncJob)
    • Demo data (useDemoService) is restricted to the canonical demo portal (DEMO_COMPANY_ID)
    • Scheduled Cron route (/api/cron/yelp-reviews) enqueues jobs for every active connection

    Environment Variables

    • YELP_CLIENT_ID / YELP_CLIENT_SECRET: OAuth credentials for connected Yelp Fusion application
    • YELP_API_KEY (legacy): Required for search/lookup helpers
    • CRON_SECRET: Bearer token for Vercel Cron to trigger /api/cron/yelp-reviews

    Scheduling

    Configure scheduler to invoke GET /api/cron/yelp-reviews every 15 minutes:

    {
      "crons": [
        { "path": "/api/cron/yelp-reviews", "schedule": "*/15 * * * *" }
      ]
    }
    

    Job Lifecycle

    • Jobs in YelpReviewSyncJob table with statuses: pending, running, completed, failed, dead_letter
    • Exponential backoff (base 60s, max 12h) with 5 attempts before dead_letter
    • Queue metrics: GET /api/connections/yelp/jobs

    Monitoring Alerts

    • Alert when dead_letter > 0
    • Alert when pending backlog consistently > 0 after cron runs
    • Alert when processedCount = 0 for multiple consecutive runs

    Google Business Profile Integration Runbook

    Overview

    • Production tenants ingest Google reviews via durable Prisma-backed queue (GoogleReviewSyncJob)
    • Demo data isolated to canonical demo portal (DEMO_COMPANY_ID)
    • Scheduled cron route (/api/cron/google-reviews) enqueues jobs for eligible connections

    Environment Variables

    • GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET: OAuth credentials from Google Business Profile project
    • GOOGLE_REDIRECT_URI (optional): Defaults to ${NEXT_PUBLIC_SITE_URL}/api/auth/google/callback
    • CRON_SECRET: Shared bearer token for /api/cron/google-reviews

    Scheduling

    Configure scheduler to call GET /api/cron/google-reviews every 15 minutes:

    {
      "crons": [
        { "path": "/api/cron/google-reviews", "schedule": "*/15 * * * *" }
      ]
    }
    

    Job Lifecycle & APIs

    • Model: GoogleReviewSyncJob with statuses: pending, running, completed, failed, dead_letter
    • Admin APIs:
      • GET /api/connections/google/jobs → queue metrics
      • POST /api/connections/google/jobs → enqueue manual sync
      • GET /api/connections/google/jobs/[jobId] → job status

    External References

    • Google My Business Review Data
    • Google My Business REST Reference

    Last Updated: February 2026

    On this page
    Pricing ModelVoice + AI ProvidersTelephony & Messaging ProvidersSocial & Integration ProvidersPhone Number ProvisioningKey Resolution FlowWhere to Configure KeysBilling IntegrationImplementation ChecklistYelp Integration RunbookOverviewEnvironment VariablesSchedulingJob LifecycleMonitoring AlertsGoogle Business Profile Integration RunbookOverviewEnvironment VariablesSchedulingJob Lifecycle & APIsExternal References