Skip to main content
Phone numbers are required for sending SMS and WhatsApp messages. You can search for available numbers, purchase them, and manage them through the API.

Search Available Numbers

Find phone numbers available for purchase:
result, err := client.PhoneNumbers.SearchAvailable(context.TODO(), zavudev.PhoneNumberSearchAvailableParams{
	CountryCode: zavudev.String("US"),
	Type:        zavudev.String("local"),
	Limit:       zavudev.Int(10),
})
if err != nil {
	panic(err)
}

for _, number := range result.Items {
	fmt.Println(number.PhoneNumber, number.Locality, number.Region)
	fmt.Println("Monthly:", number.Pricing.MonthlyPrice)
	fmt.Println("Free eligible:", number.Pricing.IsFreeEligible)
}

Search Parameters

result, err := client.PhoneNumbers.SearchAvailable(context.TODO(), zavudev.PhoneNumberSearchAvailableParams{
	CountryCode: zavudev.String("US"),    // Required: Two-letter country code
	Type:        zavudev.String("local"), // Optional: local, mobile, tollFree
	Contains:    zavudev.String("555"),   // Optional: Pattern to search for
	Limit:       zavudev.Int(20),         // Optional: Max results (default: 10, max: 50)
})

Purchase a Phone Number

result, err := client.PhoneNumbers.Purchase(context.TODO(), zavudev.PhoneNumberPurchaseParams{
	PhoneNumber: zavudev.String("+14155551234"),
	Name:        zavudev.String("Customer Support"),
})
if err != nil {
	panic(err)
}

fmt.Println(result.PhoneNumber.ID)          // pn_abc123
fmt.Println(result.PhoneNumber.PhoneNumber) // +14155551234
fmt.Println(result.PhoneNumber.Status)      // active
Your first US phone number is free. The IsFreeEligible field in search results indicates eligible numbers.

List Phone Numbers

result, err := client.PhoneNumbers.List(context.TODO(), zavudev.PhoneNumberListParams{})
if err != nil {
	panic(err)
}

for _, number := range result.Items {
	fmt.Println(number.ID, number.PhoneNumber, number.Name)
	fmt.Println("Status:", number.Status)
	fmt.Println("Assigned to:", number.SenderID)
}

// With filters
result, err := client.PhoneNumbers.List(context.TODO(), zavudev.PhoneNumberListParams{
	Status: zavudev.String("active"),
	Limit:  zavudev.Int(50),
	Cursor: zavudev.String("cursor_xxx"),
})

Get Phone Number

result, err := client.PhoneNumbers.Get(context.TODO(), "pn_abc123")
if err != nil {
	panic(err)
}

fmt.Println(result.PhoneNumber.PhoneNumber)
fmt.Println(result.PhoneNumber.Name)
fmt.Println(result.PhoneNumber.Capabilities)
fmt.Println(result.PhoneNumber.Pricing.MonthlyPrice)
fmt.Println(result.PhoneNumber.NextRenewalDate)

Update Phone Number

Update the name or sender assignment:
// Update name
result, err := client.PhoneNumbers.Update(context.TODO(), "pn_abc123", zavudev.PhoneNumberUpdateParams{
	Name: zavudev.String("Marketing Line"),
})

// Assign to a sender
result, err := client.PhoneNumbers.Update(context.TODO(), "pn_abc123", zavudev.PhoneNumberUpdateParams{
	SenderID: zavudev.String("snd_xyz789"),
})

// Unassign from sender
result, err := client.PhoneNumbers.Update(context.TODO(), "pn_abc123", zavudev.PhoneNumberUpdateParams{
	SenderID: nil,
})

Release Phone Number

Release a phone number you no longer need:
err := client.PhoneNumbers.Release(context.TODO(), "pn_abc123")
if err != nil {
	panic(err)
}
You cannot release a phone number assigned to a sender. Unassign it first.

Response Types

Phone Number Object

type OwnedPhoneNumber struct {
	ID           string                  `json:"id"`
	PhoneNumber  string                  `json:"phoneNumber"`
	Name         *string                 `json:"name"`
	Capabilities []string                `json:"capabilities"` // ["sms", "voice", "mms"]
	Status       string                  `json:"status"`       // active, suspended, pending
	SenderID     *string                 `json:"senderId"`
	Pricing      OwnedPhoneNumberPricing `json:"pricing"`
	NextRenewalDate *string              `json:"nextRenewalDate"`
	CreatedAt    string                  `json:"createdAt"`
	UpdatedAt    *string                 `json:"updatedAt"`
}

type OwnedPhoneNumberPricing struct {
	MonthlyPrice float64 `json:"monthlyPrice"`
	UpfrontCost  float64 `json:"upfrontCost"`
	MonthlyCost  float64 `json:"monthlyCost"`
	IsFreeNumber bool    `json:"isFreeNumber"`
}

Available Phone Number Object

type AvailablePhoneNumber struct {
	PhoneNumber  string                      `json:"phoneNumber"`
	FriendlyName *string                     `json:"friendlyName"`
	Locality     *string                     `json:"locality"`
	Region       *string                     `json:"region"`
	Capabilities PhoneNumberCapabilities     `json:"capabilities"`
	Pricing      AvailablePhoneNumberPricing `json:"pricing"`
}

type PhoneNumberCapabilities struct {
	SMS   bool `json:"sms"`
	Voice bool `json:"voice"`
	MMS   bool `json:"mms"`
}

type AvailablePhoneNumberPricing struct {
	MonthlyPrice   float64 `json:"monthlyPrice"`
	UpfrontPrice   float64 `json:"upfrontPrice"`
	IsFreeEligible bool    `json:"isFreeEligible"`
}

Error Handling

result, err := client.PhoneNumbers.Purchase(context.TODO(), zavudev.PhoneNumberPurchaseParams{
	PhoneNumber: zavudev.String("+14155551234"),
})
if err != nil {
	var apiErr *zavudev.APIError
	if errors.As(err, &apiErr) {
		switch apiErr.Code {
		case "insufficient_balance":
			fmt.Println("Add funds to your account")
		case "not_found":
			fmt.Println("Phone number is no longer available")
		default:
			fmt.Println("Error:", apiErr.Message)
		}
	}
	return
}