Skip to main content
This guide shows you how to automate client onboarding using the Zavu API to create partner invitations programmatically.

Overview

The Partner Invitations API allows you to:
  • Create invitation links programmatically
  • Integrate client onboarding into your own application
  • Optionally pre-assign phone numbers to invitations
  • Track invitation status and completion

Creating an Invitation

Basic Invitation

Create an invitation where the client provides their own phone number:
import Zavudev from '@zavudev/sdk';

const zavu = new Zavudev({
  apiKey: process.env["ZAVUDEV_API_KEY"],
});

const invitation = await zavu.invitations.create({
  clientName: 'Acme Corp',
  clientEmail: 'contact@acme.com',
  expiresInDays: 7,
});

console.log('Invitation URL:', invitation.url);
console.log('Token:', invitation.token);
console.log('Expires:', invitation.expiresAt);

Response

{
  "invitation": {
    "id": "jh7am5bng9p3v2x1k4r8",
    "url": "https://dashboard.zavu.dev/invite/abc123xyz",
    "token": "abc123xyz",
    "clientName": "Acme Corp",
    "clientEmail": "contact@acme.com",
    "phoneNumberId": null,
    "status": "pending",
    "senderId": null,
    "expiresAt": "2025-01-22T00:00:00.000Z",
    "createdAt": "2025-01-15T12:00:00.000Z"
  }
}

With Pre-assigned Phone Number

Pre-assign a Zavu phone number that the client will register with WhatsApp:
// First, purchase a phone number
const phoneNumber = await zavu.phoneNumbers.purchase({
  phoneNumber: '+14155551234',
  name: 'Client: Acme Corp',
});

// Then create the invitation with the phone number
const invitation = await zavu.invitations.create({
  clientName: 'Acme Corp',
  clientEmail: 'contact@acme.com',
  phoneNumberId: phoneNumber.id,
  expiresInDays: 14,
});

console.log('Invitation URL:', invitation.url);
When you pre-assign a phone number, the invitation page will show the number and automatically display the verification code when it’s received via phone call.

Create Parameters

ParameterTypeRequiredDescription
clientNamestringNoName to identify the client (max 100 chars)
clientEmailstringNoClient’s email address
clientPhonestringNoClient’s phone number (E.164 format)
phoneNumberIdstringNoPre-assign a Zavu phone number
expiresInDaysintegerNoLink validity in days (1-30, default: 7)

Listing Invitations

Retrieve all invitations for your project:
// List all invitations
const { items } = await zavu.invitations.list({});

// Filter by status
const pending = await zavu.invitations.list({
  status: 'pending',
});

for (const inv of pending.items) {
  console.log(inv.clientName, inv.status, inv.url);
}

List Parameters

ParameterTypeDescription
statusstringFilter by status: pending, in_progress, completed, expired, cancelled
limitintegerResults per page (default: 50, max: 100)
cursorstringPagination cursor

Getting Invitation Details

Retrieve details for a specific invitation:
const invitation = await zavu.invitations.get({
  invitationId: 'jh7am5bng9p3v2x1k4r8',
});

console.log('Status:', invitation.status);
console.log('Client:', invitation.clientName);

if (invitation.status === 'completed') {
  console.log('Sender ID:', invitation.senderId);
}

Response Fields

FieldTypeDescription
idstringUnique invitation ID
urlstringFull invitation URL to share with client
tokenstringURL token (part of the URL)
clientNamestringClient name
clientEmailstringClient email
phoneNumberIdstringPre-assigned phone number ID (if any)
statusstringCurrent status
senderIdstringCreated sender ID (when completed)
expiresAtstringExpiration timestamp
viewedAtstringWhen client first viewed the invitation
startedAtstringWhen client started the setup
completedAtstringWhen setup was completed

Cancelling an Invitation

Cancel an invitation to prevent it from being used:
await zavu.invitations.cancel({
  invitationId: 'jh7am5bng9p3v2x1k4r8',
});
You cannot cancel a completed invitation. Once a sender is created, manage it through the Senders API instead.

Invitation Lifecycle

Integration Examples

SaaS Onboarding Flow

Integrate WhatsApp setup into your SaaS onboarding:
async function onboardNewCustomer(customer: Customer) {
  // 1. Create the customer in your system
  await createCustomer(customer);

  // 2. Create a Zavu invitation
  const invitation = await zavu.invitations.create({
    clientName: customer.companyName,
    clientEmail: customer.email,
    expiresInDays: 14,
  });

  // 3. Send onboarding email with the invitation link
  await sendEmail({
    to: customer.email,
    subject: 'Connect Your WhatsApp Business',
    body: `
      Welcome to our platform!

      To enable WhatsApp messaging, please complete the setup:
      ${invitation.url}

      This link expires in 14 days.
    `,
  });

  // 4. Store the invitation ID for tracking
  await saveInvitationId(customer.id, invitation.id);
}

Polling for Completion

Check if a client has completed the setup:
async function checkInvitationStatus(invitationId: string) {
  const invitation = await zavu.invitations.get({ invitationId });

  switch (invitation.status) {
    case 'completed':
      console.log('Client connected! Sender ID:', invitation.senderId);
      // Start sending messages through this sender
      break;
    case 'pending':
    case 'in_progress':
      console.log('Still waiting for client to complete setup');
      break;
    case 'expired':
      console.log('Invitation expired, creating new one...');
      // Create a new invitation
      break;
    case 'cancelled':
      console.log('Invitation was cancelled');
      break;
  }

  return invitation;
}

Webhook Integration

Set up a webhook to be notified when invitations are completed:
// In your webhook handler
app.post('/webhooks/zavu', async (req, res) => {
  const event = req.body;

  if (event.type === 'sender.created') {
    // A new sender was created (possibly from an invitation)
    const sender = event.data;
    console.log('New sender:', sender.id, sender.phoneNumber);

    // Update your system
    await updateCustomerWhatsAppStatus(sender.phoneNumber, 'connected');
  }

  res.status(200).send('OK');
});

Error Handling

try {
  const invitation = await zavu.invitations.create({
    clientName: 'Acme Corp',
    phoneNumberId: 'pn_invalid',
  });
} catch (error) {
  if (error.code === 'not_found') {
    console.error('Phone number not found');
  } else if (error.code === 'invalid_request') {
    console.error('Invalid request:', error.message);
  } else {
    console.error('Unexpected error:', error);
  }
}

Common Errors

CodeDescription
not_foundPhone number or invitation not found
invalid_requestInvalid parameters
phone_number_wrong_teamPhone number belongs to a different team
already_completedCannot cancel a completed invitation

Best Practices

Store Invitation IDs

Save the invitation ID in your database to track status and link to your customer records.

Set Reminders

If an invitation is pending for several days, send a reminder to your client.

Handle Expiration

Monitor for expired invitations and automatically create new ones if needed.

Use Webhooks

Set up webhooks to get real-time notifications when senders are created.

Rate Limits

The Invitations API has the following rate limits:
EndpointLimit
Create invitation100 requests/minute
List invitations200 requests/minute
Get invitation200 requests/minute
Cancel invitation100 requests/minute

Next Steps