> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zavu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Partner Invitations

> Onboard clients to connect their WhatsApp Business accounts

Partner invitations allow you to generate links that your clients can use to connect WhatsApp Business accounts to your project. When a client completes the signup flow, a new sender is automatically created in your project.

## Phone Number Options

You have two options for the WhatsApp phone number:

1. **Client provides their own number**: The client uses their existing phone number to register for WhatsApp Business
2. **Pre-assign a Zavu number**: You purchase a phone number from Zavu and assign it to the invitation. The client registers this number under their WhatsApp Business Account

## Use Cases

* **Agencies**: Onboard client WhatsApp accounts without accessing their Facebook credentials
* **SaaS platforms**: Let customers self-service WhatsApp setup
* **Resellers**: Manage multiple client WhatsApp accounts under one project
* **Managed services**: Provision phone numbers and let clients complete the WhatsApp verification

## How It Works

```mermaid theme={null}
sequenceDiagram
    participant Partner as Your App
    participant Zavu as Zavu API
    participant Client as Client
    participant Meta as Meta

    Partner->>Zavu: POST /v1/invitations
    Zavu-->>Partner: { url, token }
    Partner->>Client: Share invitation URL
    Client->>Zavu: Open invitation page
    Client->>Meta: Complete embedded signup
    Meta-->>Zavu: OAuth callback
    Zavu->>Zavu: Create sender
    Client-->>Partner: WhatsApp connected!
```

## Create an Invitation

### Client provides their own number

```bash theme={null}
curl -X POST https://api.zavu.dev/v1/invitations \
  -H "Authorization: Bearer $ZAVU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "clientName": "Acme Corp",
    "clientEmail": "contact@acme.com",
    "expiresInDays": 14
  }'
```

### Pre-assign a Zavu phone number

First, purchase a phone number from Zavu, then create the invitation with the `phoneNumberId`:

```bash theme={null}
curl -X POST https://api.zavu.dev/v1/invitations \
  -H "Authorization: Bearer $ZAVU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "clientName": "Acme Corp",
    "clientEmail": "contact@acme.com",
    "phoneNumberId": "pn_abc123",
    "expiresInDays": 14
  }'
```

When a phone number is pre-assigned, the client will see the number on the invitation page and use it during the WhatsApp registration. The verification code will be received via phone call to that number.

### Response

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

Share the `url` with your client. They will complete Meta's embedded signup flow to connect their WhatsApp Business account.

## Invitation Lifecycle

| Status        | Description                            |
| ------------- | -------------------------------------- |
| `pending`     | Invitation created, waiting for client |
| `in_progress` | Client started the signup flow         |
| `completed`   | WhatsApp connected, sender created     |
| `expired`     | Invitation expired before completion   |
| `cancelled`   | Invitation was cancelled               |

## List Invitations

```bash theme={null}
curl https://api.zavu.dev/v1/invitations \
  -H "Authorization: Bearer $ZAVU_API_KEY"
```

Filter by status:

```bash theme={null}
curl "https://api.zavu.dev/v1/invitations?status=completed" \
  -H "Authorization: Bearer $ZAVU_API_KEY"
```

## Get Invitation Details

```bash theme={null}
curl https://api.zavu.dev/v1/invitations/jh7am5bng9p3v2x1k4r8 \
  -H "Authorization: Bearer $ZAVU_API_KEY"
```

## Cancel an Invitation

Cancel an active invitation to prevent the client from using it:

```bash theme={null}
curl -X POST https://api.zavu.dev/v1/invitations/jh7am5bng9p3v2x1k4r8/cancel \
  -H "Authorization: Bearer $ZAVU_API_KEY"
```

<Note>
  You cannot cancel a completed invitation. Once a sender is created, you can delete it through the senders API.
</Note>

## After Completion

When a client completes the signup flow:

1. A new **sender** is created in your project with WhatsApp enabled
2. The sender's phone number is the client's registered WhatsApp number
3. The invitation status changes to `completed`
4. The `senderId` field contains the ID of the created sender

You can then use this sender to send WhatsApp messages on behalf of your client:

```bash theme={null}
curl -X POST https://api.zavu.dev/v1/messages \
  -H "Authorization: Bearer $ZAVU_API_KEY" \
  -H "Zavu-Sender: snd_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "channel": "whatsapp",
    "messageType": "template",
    "content": {
      "templateId": "tmpl_xyz789",
      "templateVariables": {
        "1": "John"
      }
    }
  }'
```

## SDK Examples

<CodeGroup>
  ```typescript TypeScript theme={null}
  import Zavudev from '@zavudev/sdk';

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

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

  console.log('Share this URL:', invitation.url);

  // List invitations
  const { items } = await zavu.invitations.list({ status: 'pending' });

  // Cancel invitation
  await zavu.invitations.cancel(invitation.id);
  ```

  ```python Python theme={null}
  import os
  from zavudev import Zavudev

  zavu = Zavudev(
      api_key=os.environ.get("ZAVUDEV_API_KEY"),
  )

  # Create invitation
  invitation = zavu.invitations.create(
      client_name="Acme Corp",
      client_email="contact@acme.com",
      expires_in_days=14
  )

  print(f"Share this URL: {invitation.url}")

  # List invitations
  result = zavu.invitations.list(status="pending")

  # Cancel invitation
  zavu.invitations.cancel(invitation_id=invitation.id)
  ```

  ```ruby Ruby theme={null}
  require 'zavudev'

  zavu = Zavudev::Client.new(
    api_key: ENV['ZAVUDEV_API_KEY']
  )

  # Create invitation
  invitation = zavu.invitations.create(
    client_name: "Acme Corp",
    client_email: "contact@acme.com",
    expires_in_days: 14
  )

  puts "Share this URL: #{invitation.url}"

  # List invitations
  result = zavu.invitations.list(status: "pending")

  # Cancel invitation
  zavu.invitations.cancel(invitation.id)
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      "github.com/zavudev/sdk-go"
  )

  func main() {
      client := zavudev.NewClient(
          zavudev.WithAPIKey(os.Getenv("ZAVUDEV_API_KEY")),
      )

      // Create invitation
      invitation, err := client.Invitations.Create(context.TODO(), zavudev.InvitationCreateParams{
          ClientName:    zavudev.String("Acme Corp"),
          ClientEmail:   zavudev.String("contact@acme.com"),
          ExpiresInDays: zavudev.Int(14),
      })

      fmt.Println("Share this URL:", invitation.URL)

      // List invitations
      result, err := client.Invitations.List(context.TODO(), zavudev.InvitationListParams{
          Status: zavudev.String("pending"),
      })

      // Cancel invitation
      _, err = client.Invitations.Cancel(context.TODO(), invitation.ID)
  }
  ```

  ```php PHP theme={null}
  $zavu = new Zavudev\Client(['apiKey' => getenv('ZAVUDEV_API_KEY')]);

  // Create invitation
  $invitation = $zavu->invitations->create([
      'clientName' => 'Acme Corp',
      'clientEmail' => 'contact@acme.com',
      'expiresInDays' => 14,
  ]);

  echo "Share this URL: " . $invitation->url . "\n";

  // List invitations
  $result = $zavu->invitations->list(['status' => 'pending']);

  // Cancel invitation
  $zavu->invitations->cancel($invitation->id);
  ```
</CodeGroup>

## Best Practices

1. **Set appropriate expiration**: Use shorter expirations (3-7 days) for urgent onboarding
2. **Track client info**: Include `clientName` and `clientEmail` for easier management
3. **Monitor status**: Check for `expired` or `cancelled` invitations and resend if needed
4. **Webhooks**: Configure webhooks on the resulting sender to receive inbound messages
