Beta Notice: The go-infinity-sdk is currently in Beta and is not recommended for production deployments. Please use with caution.
A comprehensive Go client library for the Pexip Infinity Management API, providing easy access to all four API categories: Configuration, Status, History, and Command APIs.
- Full API Coverage: Complete support for all Pexip Infinity Management API endpoints
- Type-Safe: Strongly typed Go structs for all API requests and responses
- Authentication: Support for Basic Auth, Token Auth, Bearer Auth, and custom authentication
- Retry Mechanism: Built-in exponential backoff with jitter for reliable API calls
- Context Support: All operations support Go context for cancellation and timeouts
- Comprehensive Testing: Extensive test coverage with mocks using testify/mock
- Flexible Configuration: Configurable base URLs, HTTP clients, and authentication methods
go get github.com/pexip/go-infinity-sdk/v38package main
import (
"context"
"fmt"
"log"
infinity "github.com/pexip/go-infinity-sdk/v38"
)
func main() {
// Create a new client with basic authentication and retry configuration
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "your-password"),
// Optional: customize retry behavior (default is 3 retries with exponential backoff)
infinity.WithMaxRetries(2),
)
if err != nil {
log.Fatal(err)
}
// Get system status
ctx := context.Background()
status, err := client.Status.GetSystemStatus(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("System Status: %s, Version: %s\n", status.Status, status.Version)
}client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
)client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithTokenAuth("your-api-token"),
)import "github.com/pexip/go-infinity-sdk/v38/auth"
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithAuth(auth.NewBearerAuth("your-bearer-token")),
)import "github.com/pexip/go-infinity-sdk/v38/auth"
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithAuth(auth.NewCustomAuth("X-API-Key", "your-api-key")),
)The SDK includes a robust retry mechanism with exponential backoff to handle transient failures:
// Default configuration is applied automatically
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
// Retries up to 3 times with exponential backoff
)import "time"
retryConfig := &infinity.RetryConfig{
MaxRetries: 5, // Maximum number of retries
BackoffMin: 500 * time.Millisecond, // Minimum backoff duration
BackoffMax: 30 * time.Second, // Maximum backoff duration
Multiplier: 2.0, // Backoff multiplier
JitterFactor: 0.1, // Jitter factor (0.0-1.0)
}
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
infinity.WithRetryConfig(retryConfig),
)// Disable retries completely
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
infinity.WithNoRetries(),
)
// Set only max retries (uses default for other settings)
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
infinity.WithMaxRetries(1),
)The retry mechanism automatically retries on:
- HTTP Status Codes: 429, 500, 502, 503, 504
- Network Errors: Connection refused, timeouts, DNS failures
It will NOT retry on:
- Client Errors: 4xx status codes (400, 401, 403, 404, etc.)
- Context Cancellation: Respects context timeouts and cancellation
package main
import (
"context"
"fmt"
"log"
infinity "github.com/pexip/go-infinity-sdk/v38"
"github.com/pexip/go-infinity-sdk/v38/config"
)
func main() {
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Create a new conference
createReq := &config.ConferenceCreateRequest{
Name: "My Test Conference",
Description: "A test conference for demonstration",
ServiceType: "conference",
AllowGuests: true,
GuestsMuted: false,
}
conference, err := client.Config.CreateConference(ctx, createReq)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created conference: %s (ID: %d)\n", conference.Name, conference.ID)
// List conferences with pagination and search
listOpts := &config.ListOptions{}
listOpts.Limit = 10
listOpts.Offset = 0
listOpts.Search = "test"
conferences, err := client.Config.ListConferences(ctx, listOpts)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d conferences\n", len(conferences.Objects))
for _, conf := range conferences.Objects {
fmt.Printf("- %s (ID: %d)\n", conf.Name, conf.ID)
}
// Update a conference
updateReq := &config.ConferenceUpdateRequest{
Description: "Updated description",
}
updatedConf, err := client.Config.UpdateConference(ctx, conference.ID, updateReq)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Updated conference description: %s\n", updatedConf.Description)
// Delete the conference
err = client.Config.DeleteConference(ctx, conference.ID)
if err != nil {
log.Fatal(err)
}
fmt.Println("Conference deleted successfully")
}// Create a location
createLocReq := &config.LocationCreateRequest{
Name: "New York Office",
Description: "Main office location",
}
location, err := client.Config.CreateLocation(ctx, createLocReq)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created location: %s (ID: %d)\n", location.Name, location.ID)
// List all locations
locations, err := client.Config.ListLocations(ctx, nil)
if err != nil {
log.Fatal(err)
}
for _, loc := range locations.Objects {
fmt.Printf("Location: %s - %s\n", loc.Name, loc.Description)
}package main
import (
"context"
"fmt"
"log"
infinity "github.com/pexip/go-infinity-sdk/v38"
"github.com/pexip/go-infinity-sdk/v38/status"
)
func main() {
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Get system status
sysStatus, err := client.Status.GetSystemStatus(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("System Status: %s\n", sysStatus.Status)
fmt.Printf("Version: %s\n", sysStatus.Version)
fmt.Printf("Uptime: %d seconds\n", sysStatus.Uptime)
fmt.Printf("CPU Load: %.2f%%\n", sysStatus.CPULoad)
fmt.Printf("Memory Usage: %d/%d MB\n",
sysStatus.UsedMemory/1024/1024,
sysStatus.TotalMemory/1024/1024)
// List active conferences
conferences, err := client.Status.ListConferences(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nActive Conferences: %d\n", len(conferences.Objects))
for _, conf := range conferences.Objects {
fmt.Printf("- %s: %d participants (Started: %t)\n",
conf.Name, conf.ParticipantCount, conf.Started)
}
// List participants with pagination
participantOpts := &status.ListOptions{}
participantOpts.Limit = 20
participants, err := client.Status.ListParticipants(ctx, participantOpts)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nActive Participants: %d\n", len(participants.Objects))
for _, participant := range participants.Objects {
fmt.Printf("- %s (%s) in %s - Muted: %t\n",
participant.DisplayName,
participant.Role,
participant.ConferenceName,
participant.IsMuted)
}
// List worker nodes
workers, err := client.Status.ListWorkers(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nWorker Nodes: %d\n", len(workers.Objects))
for _, worker := range workers.Objects {
fmt.Printf("- %s (%s): CPU %.1f%%, Memory %.1f%%, %d conferences\n",
worker.HostName,
worker.Status,
worker.CPU,
worker.Memory,
worker.Conferences)
}
// List system alarms
alarms, err := client.Status.ListAlarms(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nSystem Alarms: %d\n", len(alarms.Objects))
for _, alarm := range alarms.Objects {
status := "ACTIVE"
if alarm.Cleared {
status = "CLEARED"
}
fmt.Printf("- [%s] %s: %s (%s)\n",
alarm.Level,
alarm.Name,
alarm.Details,
status)
}
}package main
import (
"context"
"fmt"
"log"
"time"
infinity "github.com/pexip/go-infinity-sdk/v38"
"github.com/pexip/go-infinity-sdk/v38/history"
)
func main() {
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Get conference history for the last 24 hours
yesterday := time.Now().Add(-24 * time.Hour)
listOpts := &history.ListOptions{}
listOpts.Limit = 50
listOpts.StartTime = &yesterday
listOpts.Search = "weekly"
conferences, err := client.History.ListConferences(ctx, listOpts)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Conference History (last 24h): %d conferences\n", len(conferences.Objects))
for _, conf := range conferences.Objects {
duration := time.Duration(conf.DurationSeconds) * time.Second
fmt.Printf("- %s: %v duration, %d participants\n",
conf.Name,
duration,
conf.TotalParticipants)
}
// Get participant history for a specific conference
if len(conferences.Objects) > 0 {
confID := conferences.Objects[0].ID
participants, err := client.History.ListParticipantsByConference(ctx, confID, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nParticipants in conference %d:\n", confID)
for _, participant := range participants.Objects {
duration := time.Duration(participant.DurationSeconds) * time.Second
fmt.Printf("- %s (%s): %v duration, %s reason\n",
participant.DisplayName,
participant.Role,
duration,
participant.DisconnectReason)
}
// Get media stream details for the first participant
if len(participants.Objects) > 0 {
participantID := participants.Objects[0].ID
streams, err := client.History.ListMediaStreamsByParticipant(ctx, participantID, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nMedia streams for participant %d:\n", participantID)
for _, stream := range streams.Objects {
fmt.Printf("- %s %s: %s codec, %d kbps\n",
stream.StreamType,
stream.Direction,
stream.Codec,
stream.Bitrate/1000)
}
}
}
}package main
import (
"context"
"fmt"
"log"
infinity "github.com/pexip/go-infinity-sdk/v38"
"github.com/pexip/go-infinity-sdk/v38/command"
)
func main() {
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithBasicAuth("admin", "password"),
)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Get current participants to demonstrate commands
participants, err := client.Status.ListParticipants(ctx, nil)
if err != nil {
log.Fatal(err)
}
if len(participants.Objects) == 0 {
fmt.Println("No active participants found")
return
}
participant := participants.Objects[0]
participantUUID := participant.UUID
conferenceID := participant.ConferenceID
fmt.Printf("Managing participant: %s (UUID: %s)\n", participant.DisplayName, participantUUID)
// Mute a participant
result, err := client.Command.MuteParticipant(ctx, participantUUID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Mute result: %s - %s\n", result.Status, result.Message)
// Send a message to the participant
result, err = client.Command.SendMessageToParticipant(ctx, participantUUID, "Welcome to the conference!")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Message sent: %s\n", result.Status)
// Spotlight the participant
result, err = client.Command.SpotlightParticipant(ctx, participantUUID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Spotlight result: %s\n", result.Status)
// Promote participant to chair
result, err = client.Command.PromoteParticipant(ctx, participantUUID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Promotion result: %s\n", result.Status)
// Lock the conference
result, err = client.Command.LockConference(ctx, conferenceID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Conference lock result: %s\n", result.Status)
// Send message to all participants in the conference
result, err = client.Command.SendMessageToConference(ctx, conferenceID, "This conference is now locked")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Conference message result: %s\n", result.Status)
// Transfer participant to another conference
transferOpts := &command.TransferOptions{
Role: "guest",
}
result, err = client.Command.TransferParticipant(ctx, participantUUID, "other-conference", transferOpts)
if err != nil {
log.Printf("Transfer failed (expected if 'other-conference' doesn't exist): %v\n", err)
} else {
fmt.Printf("Transfer result: %s\n", result.Status)
}
// Start a conference programmatically
result, err = client.Command.StartConference(ctx, "scheduled-meeting")
if err != nil {
log.Printf("Start conference failed (expected if conference doesn't exist): %v\n", err)
} else {
fmt.Printf("Conference start result: %s\n", result.Status)
}
}import (
"net/http"
"time"
)
// Create a custom HTTP client with timeout and custom transport
httpClient := &http.Client{
Timeout: 60 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithHTTPClient(httpClient),
infinity.WithBasicAuth("admin", "password"),
)For more fine-grained control over HTTP transport settings (proxies, TLS configuration, connection pooling), you can use WithTransport:
import (
"crypto/tls"
"net/http"
"net/url"
"time"
)
// Example 1: Custom transport with proxy and TLS settings
proxyURL, _ := url.Parse("http://proxy.company.com:8080")
customTransport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, // Only for testing!
},
MaxIdleConns: 50,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 30 * time.Second,
DisableCompression: true,
}
client, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithTransport(customTransport),
infinity.WithBasicAuth("admin", "password"),
)
// Example 2: Transport with client certificates
cert, _ := tls.LoadX509KeyPair("client.crt", "client.key")
tlsTransport := &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{cert},
},
}
tlsClient, err := infinity.New(
infinity.WithBaseURL("https://your-pexip-server.com"),
infinity.WithTransport(tlsTransport),
infinity.WithBasicAuth("admin", "password"),
)import "github.com/pexip/go-infinity-sdk/v38"
// All API calls return typed errors
conferences, err := client.Config.ListConferences(ctx, nil)
if err != nil {
// Check if it's an API error
if apiErr, ok := err.(*infinity.APIError); ok {
fmt.Printf("API Error %d: %s\n", apiErr.StatusCode, apiErr.Message)
if apiErr.Details != "" {
fmt.Printf("Details: %s\n", apiErr.Details)
}
} else {
// Handle other types of errors (network, timeout, etc.)
fmt.Printf("Other error: %v\n", err)
}
}import (
"context"
"time"
)
// Create a context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// Use the context for all API calls
conferences, err := client.Config.ListConferences(ctx, nil)
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
fmt.Println("Request timed out")
}
}For questions and support, please refer to the Pexip Infinity API Documentation or open an issue in this repository.