Early Access Program

The JavaScript SDK is currently in private beta. This documentation is provided for approved partners and early access participants.

Interested in early access? Contact us at sdk@callbird.com with your use case.

JavaScript SDK

Native JavaScript control over Callbird. Check availability in real-time, trigger calls programmatically, and receive events for your analytics and CRM integrations.

Native API Calls

Availability checks via fetch API. No overhead, instant responses.

Real-time Events

Get notified when calls start, connect, and end. Perfect for analytics.

Full Control

You decide when and how the call interface appears. Your UX, your rules.

What You Can Build

  • Custom call buttons with real-time availability status
  • Conditional call availability based on page context or user state
  • CRM integrations - log calls to Salesforce, HubSpot, etc.
  • Analytics tracking - call duration, outcomes, visitor data
  • Multi-step forms that initiate calls on completion

How It Works

The SDK provides native JavaScript methods for checking availability and handling events. When you initiate a call, a lightweight modal overlay opens with the Callbird video interface. Your page stays in control - you receive events throughout the call lifecycle and can close the modal programmatically.

Installation

Add the SDK to your page with a single script tag. No build tools required.

<script src="https://www.callbird.com/sdk/v1/callbird.min.js"></script>

What Gets Loaded

  • ~6KB gzipped - Minimal footprint
  • Async loading - Doesn't block page render
  • No dependencies - Pure JavaScript, works everywhere
  • Exposes window.Callbird globally

Initialization

Create a Callbird instance with your organization ID. The SDK immediately begins polling for availability.

const callbird = new Callbird({
  orgId: 'YOUR_ORG_ID'
});

// Wait for ready state
callbird.on('ready', function() {
  console.log('Callbird ready');
  console.log('Status:', callbird.availability); // 'available', 'busy', or 'offline'
});

Important: Your organization ID is found in Dashboard → Settings → Company → API. This is different from your company page URL slug.

Options

Option Type Default Description
orgId string required Your Callbird organization ID
pollInterval number 30000 How often to check availability (ms)
debug boolean false Enable console logging

checkAvailability()

Fetch current availability status. Returns a promise with detailed availability info.

callbird.checkAvailability(): Promise<AvailabilityResult>
const status = await callbird.checkAvailability();

console.log(status);
// {
//   status: 'available',      // 'available' | 'busy' | 'offline'
//   availableCount: 3,        // Team members currently available
//   message: 'Team is online' // Human-readable status
// }

// Use it to control your UI
if (status.status === 'available') {
  showCallButton();
} else {
  showOfflineMessage(status.message);
}

Note: This makes a real API call to get fresh data. For cached status, use callbird.availability which is updated automatically via polling.

startCall()

Initiate a video call. Opens the call interface in a modal overlay.

callbird.startCall(options?): Promise<CallSession>
// Basic call
callbird.startCall();

// With visitor data
callbird.startCall({
  visitor: {
    name: 'Jane Smith',
    email: 'jane@example.com',
    company: 'Acme Inc'
  }
});

// Route to specific team member
callbird.startCall({
  userId: 'jack'
});

Options

Option Type Description
visitor object Visitor info to pass to call recipient
userId string Route to specific team member (username)

openModal()

Open the Callbird interface without starting a call. Shows the intro video and call button.

callbird.openModal(options?): void
// Open modal showing intro video
callbird.openModal();

// With visitor data pre-filled
callbird.openModal({
  visitor: {
    name: document.getElementById('name').value,
    email: document.getElementById('email').value
  }
});

closeModal()

Close the modal programmatically. Does not end an active call.

callbird.closeModal(): void
callbird.closeModal();

Event Handling

Subscribe to events to track call lifecycle, update your UI, and integrate with analytics.

// Availability changes
callbird.on('availabilityChange', function(status) {
  updateStatusBadge(status.status);
});

// Call lifecycle
callbird.on('callStarted', function(data) {
  analytics.track('call_initiated', {
    visitor: data.visitor
  });
});

callbird.on('callConnected', function(data) {
  console.log('Connected to:', data.connectedUserName);
});

callbird.on('callEnded', function(data) {
  analytics.track('call_completed', {
    duration: data.duration,
    outcome: data.reason
  });

  // Maybe show a feedback form
  if (data.duration > 60) {
    showSatisfactionSurvey();
  }
});

// Unsubscribe
callbird.off('callEnded', myHandler);

Event Types

ready

SDK initialized and first availability check complete.

availabilityChange

Availability status changed.

{ status: 'available' | 'busy' | 'offline', availableCount: number }
modalOpened

Call interface opened.

modalClosed

Call interface closed.

{ reason: 'user' | 'api' | 'callEnded' }
callStarted

Call initiated, waiting for connection.

{ sessionId: string, visitor: object | null }
callConnected

Both parties connected, video streaming.

{ sessionId: string, connectedUserId: string, connectedUserName: string }
callEnded

Call ended.

{ sessionId: string, duration: number, reason: 'completed' | 'rejected' | 'missed' | 'cancelled' }
error

An error occurred.

{ code: string, message: string }

Visitor Data

Pass visitor information to provide context for call recipients. Integrates with Signed Visitor Data for verified information.

callbird.startCall({
  visitor: {
    name: 'Jane Smith',
    email: 'jane@example.com',
    company: 'Acme Inc',
    phone: '+1-555-123-4567',
    custom: {
      plan: 'Enterprise',
      accountId: 'acc_12345'
    }
  }
});

// With signed data (verified by your backend)
callbird.startCall({
  visitor: {
    name: 'Jane Smith',
    email: 'jane@example.com',
    signature: 'HMAC_FROM_YOUR_SERVER',
    timestamp: Math.floor(Date.now() / 1000)
  }
});

Fields

Field Type Description
name string Visitor's name
email string Visitor's email
company string Company name
phone string Phone number
custom object Any additional key-value pairs
signature string HMAC signature for verified data
timestamp number Unix timestamp for signature

Custom Styling

Override default colors to match your brand using CSS custom properties.

:root {
  --callbird-primary: #212529;
  --callbird-primary-hover: #374151;
  --callbird-success: #22c55e;
  --callbird-warning: #f59e0b;
  --callbird-error: #ef4444;
  --callbird-radius: 12px;
}

Integration Examples

Custom Call Button with Status

<button id="call-btn" disabled>
  <span class="status-dot"></span>
  Talk to Sales
</button>

<script src="https://www.callbird.com/sdk/v1/callbird.min.js"></script>
<script>
const callbird = new Callbird({ orgId: 'YOUR_ORG_ID' });
const btn = document.getElementById('call-btn');
const dot = btn.querySelector('.status-dot');

callbird.on('ready', function() {
  updateButton(callbird.availability);
});

callbird.on('availabilityChange', function(status) {
  updateButton(status.status);
});

function updateButton(status) {
  btn.disabled = status !== 'available';
  dot.className = 'status-dot status-' + status;
  btn.querySelector('span:last-child').textContent =
    status === 'available' ? 'Talk to Sales' : 'Team Offline';
}

btn.addEventListener('click', function() {
  callbird.startCall();
});
</script>

<style>
.status-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  display: inline-block;
  margin-right: 8px;
}
.status-available { background: #22c55e; }
.status-busy { background: #f59e0b; }
.status-offline { background: #9ca3af; }
</style>

Form Submission to Call

<form id="contact-form">
  <input type="text" name="name" placeholder="Your name" required>
  <input type="email" name="email" placeholder="Email" required>
  <input type="text" name="company" placeholder="Company">
  <button type="submit">Start Video Call</button>
</form>

<script>
document.getElementById('contact-form').addEventListener('submit', function(e) {
  e.preventDefault();

  const formData = new FormData(this);

  callbird.startCall({
    visitor: {
      name: formData.get('name'),
      email: formData.get('email'),
      company: formData.get('company')
    }
  });
});
</script>

Analytics Integration

callbird.on('callStarted', function(data) {
  // Google Analytics 4
  gtag('event', 'call_started', {
    visitor_email: data.visitor?.email
  });

  // Segment
  analytics.track('Call Started', {
    visitorEmail: data.visitor?.email
  });
});

callbird.on('callEnded', function(data) {
  gtag('event', 'call_ended', {
    duration_seconds: data.duration,
    outcome: data.reason
  });

  analytics.track('Call Ended', {
    duration: data.duration,
    outcome: data.reason
  });
});

callbird.on('callConnected', function(data) {
  // Log to your CRM
  fetch('/api/log-call', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      agent: data.connectedUserName,
      sessionId: data.sessionId
    })
  });
});

Error Handling

Handle errors gracefully to provide a good user experience.

callbird.on('error', function(error) {
  switch (error.code) {
    case 'UNAVAILABLE':
      showMessage('No one is available right now. Try again later.');
      break;
    case 'PERMISSION_DENIED':
      showMessage('Please allow camera and microphone access.');
      break;
    case 'NETWORK_ERROR':
      showMessage('Connection failed. Check your internet.');
      break;
    default:
      showMessage('Something went wrong. Please try again.');
  }
});

Error Codes

Code Description
UNAVAILABLE No team members available
PERMISSION_DENIED Camera/mic permission denied
NETWORK_ERROR Connection failed
INVALID_ORG Invalid organization ID
CALL_REJECTED Call was rejected