or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

accounts.mdauthentication.mdconversations.mdfilters.mdindex.mdinstance.mdlists.mdmedia.mdnotifications.mdpolls.mdreports.mdsearch.mdstatuses.mdstreaming.mdtags.mdtimelines.mdtypes.md
tile.json

instance.mddocs/

Instance Information

Complete instance metadata, configuration, and statistics operations.

Overview

Instance endpoints provide information about Mastodon servers including configuration, statistics, activity, and federated peers.

Types

Instance

type Instance struct {
    URI            string
    Title          string
    Description    string
    EMail          string
    Version        string
    Thumbnail      string
    URLs           map[string]string
    Stats          *InstanceStats
    Languages      []string
    ContactAccount *Account
    Configuration  *InstanceConfig
}

Instance holds information for a Mastodon instance.

Fields:

  • URI - Instance domain (e.g., "mastodon.social")
  • Title - Instance name
  • Description - Instance description (HTML)
  • EMail - Admin contact email
  • Version - Mastodon version string
  • Thumbnail - Instance thumbnail image URL
  • URLs - Streaming API URLs and other endpoints
  • Stats - Instance statistics
  • Languages - Supported language codes
  • ContactAccount - Contact account for admin
  • Configuration - Instance configuration limits

Method:

func (c *Instance) GetConfig() *InstanceConfig

Returns instance configuration.

InstanceConfig

type InstanceConfig struct {
    Accounts         *InstanceConfigMap
    Statuses         *InstanceConfigMap
    MediaAttachments map[string]interface{}
    Polls            *InstanceConfigMap
}

InstanceConfig holds configuration limits accessible to clients.

Fields:

  • Accounts - Account-related limits
  • Statuses - Status-related limits
  • MediaAttachments - Media file size and type limits
  • Polls - Poll-related limits

InstanceConfigMap

type InstanceConfigMap map[string]interface{}

InstanceConfigMap is a type alias for configuration maps.

Configuration examples:

  • Accounts: max_featured_tags, max_pinned_statuses
  • Statuses: max_characters, max_media_attachments
  • MediaAttachments: supported_mime_types, image_size_limit, video_size_limit
  • Polls: max_options, max_characters_per_option, min_expiration, max_expiration

InstanceStats

type InstanceStats struct {
    UserCount   int64
    StatusCount int64
    DomainCount int64
}

InstanceStats holds statistics for a Mastodon instance.

Fields:

  • UserCount - Total registered users
  • StatusCount - Total statuses posted
  • DomainCount - Number of known instances (federated peers)

WeeklyActivity

type WeeklyActivity struct {
    Week          Unixtime
    Statuses      int64
    Logins        int64
    Registrations int64
}

WeeklyActivity holds weekly activity statistics.

Fields:

  • Week - Week timestamp
  • Statuses - Number of statuses posted that week
  • Logins - Number of logins that week
  • Registrations - Number of new registrations that week

Instance Operations

GetInstance { .api }

func (c *Client) GetInstance(ctx context.Context) (*Instance, error)

Returns information about the instance.

Parameters:

  • ctx - Context for cancellation/timeout

Returns: Instance information or error

Example:

instance, err := client.GetInstance(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Instance: %s\n", instance.Title)
fmt.Printf("URI: %s\n", instance.URI)
fmt.Printf("Version: %s\n", instance.Version)
fmt.Printf("Description: %s\n", instance.Description)

if instance.Stats != nil {
    fmt.Printf("\nStatistics:\n")
    fmt.Printf("  Users: %d\n", instance.Stats.UserCount)
    fmt.Printf("  Statuses: %d\n", instance.Stats.StatusCount)
    fmt.Printf("  Federated instances: %d\n", instance.Stats.DomainCount)
}

if instance.ContactAccount != nil {
    fmt.Printf("\nAdmin: @%s\n", instance.ContactAccount.Acct)
}

GetInstanceActivity { .api }

func (c *Client) GetInstanceActivity(ctx context.Context) ([]*WeeklyActivity, error)

Returns instance activity statistics by week.

Parameters:

  • ctx - Context for cancellation/timeout

Returns: Slice of WeeklyActivity objects or error

Example:

activities, err := client.GetInstanceActivity(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Println("Weekly Activity:")
for _, activity := range activities {
    fmt.Printf("Week of %s:\n", time.Time(activity.Week).Format("2006-01-02"))
    fmt.Printf("  Statuses: %d\n", activity.Statuses)
    fmt.Printf("  Logins: %d\n", activity.Logins)
    fmt.Printf("  New users: %d\n", activity.Registrations)
}

GetInstancePeers { .api }

func (c *Client) GetInstancePeers(ctx context.Context) ([]string, error)

Returns instance peers (other federated instances this instance knows about).

Parameters:

  • ctx - Context for cancellation/timeout

Returns: Slice of peer domain strings or error

Example:

peers, err := client.GetInstancePeers(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Known instances: %d\n", len(peers))
for i, peer := range peers {
    if i < 10 { // Show first 10
        fmt.Printf("  %s\n", peer)
    }
}
if len(peers) > 10 {
    fmt.Printf("  ... and %d more\n", len(peers)-10)
}

Usage Examples

Example: Instance Information Display

func displayInstanceInfo(client *mastodon.Client) error {
    ctx := context.Background()

    instance, err := client.GetInstance(ctx)
    if err != nil {
        return err
    }

    fmt.Println("╔" + strings.Repeat("═", 60) + "╗")
    fmt.Printf("║ %-58s ║\n", instance.Title)
    fmt.Println("╠" + strings.Repeat("═", 60) + "╣")
    fmt.Printf("║ URI:        %-47s ║\n", instance.URI)
    fmt.Printf("║ Version:    %-47s ║\n", instance.Version)

    if instance.Stats != nil {
        fmt.Println("╠" + strings.Repeat("═", 60) + "╣")
        fmt.Printf("║ Users:      %-47d ║\n", instance.Stats.UserCount)
        fmt.Printf("║ Posts:      %-47d ║\n", instance.Stats.StatusCount)
        fmt.Printf("║ Federation: %-47d ║\n", instance.Stats.DomainCount)
    }

    if len(instance.Languages) > 0 {
        fmt.Println("╠" + strings.Repeat("═", 60) + "╣")
        langs := strings.Join(instance.Languages, ", ")
        fmt.Printf("║ Languages:  %-47s ║\n", langs)
    }

    fmt.Println("╚" + strings.Repeat("═", 60) + "╝")

    return nil
}

Example: Check Instance Limits

func checkInstanceLimits(client *mastodon.Client) error {
    ctx := context.Background()

    instance, err := client.GetInstance(ctx)
    if err != nil {
        return err
    }

    if instance.Configuration == nil {
        fmt.Println("Configuration not available")
        return nil
    }

    fmt.Println("Instance Limits:")

    // Status limits
    if instance.Configuration.Statuses != nil {
        if maxChars, ok := (*instance.Configuration.Statuses)["max_characters"]; ok {
            fmt.Printf("  Max status length: %v characters\n", maxChars)
        }
        if maxMedia, ok := (*instance.Configuration.Statuses)["max_media_attachments"]; ok {
            fmt.Printf("  Max media per post: %v\n", maxMedia)
        }
    }

    // Media limits
    if instance.Configuration.MediaAttachments != nil {
        if imgLimit, ok := instance.Configuration.MediaAttachments["image_size_limit"]; ok {
            fmt.Printf("  Max image size: %v bytes\n", imgLimit)
        }
        if vidLimit, ok := instance.Configuration.MediaAttachments["video_size_limit"]; ok {
            fmt.Printf("  Max video size: %v bytes\n", vidLimit)
        }
    }

    // Poll limits
    if instance.Configuration.Polls != nil {
        if maxOpts, ok := (*instance.Configuration.Polls)["max_options"]; ok {
            fmt.Printf("  Max poll options: %v\n", maxOpts)
        }
        if maxExp, ok := (*instance.Configuration.Polls)["max_expiration"]; ok {
            fmt.Printf("  Max poll duration: %v seconds\n", maxExp)
        }
    }

    return nil
}

Example: Activity Analysis

func analyzeInstanceActivity(client *mastodon.Client) error {
    ctx := context.Background()

    activities, err := client.GetInstanceActivity(ctx)
    if err != nil {
        return err
    }

    if len(activities) == 0 {
        fmt.Println("No activity data available")
        return nil
    }

    fmt.Println("Instance Activity Analysis")
    fmt.Println(strings.Repeat("=", 50))

    // Calculate totals and averages
    var totalStatuses, totalLogins, totalRegistrations int64
    for _, activity := range activities {
        totalStatuses += activity.Statuses
        totalLogins += activity.Logins
        totalRegistrations += activity.Registrations
    }

    weeks := len(activities)
    fmt.Printf("\nLast %d weeks:\n", weeks)
    fmt.Printf("  Total statuses:      %d (avg %.1f/week)\n",
        totalStatuses, float64(totalStatuses)/float64(weeks))
    fmt.Printf("  Total logins:        %d (avg %.1f/week)\n",
        totalLogins, float64(totalLogins)/float64(weeks))
    fmt.Printf("  Total registrations: %d (avg %.1f/week)\n",
        totalRegistrations, float64(totalRegistrations)/float64(weeks))

    // Find most active week
    maxStatuses := int64(0)
    var mostActiveWeek time.Time
    for _, activity := range activities {
        if activity.Statuses > maxStatuses {
            maxStatuses = activity.Statuses
            mostActiveWeek = time.Time(activity.Week)
        }
    }

    fmt.Printf("\nMost active week: %s (%d statuses)\n",
        mostActiveWeek.Format("2006-01-02"), maxStatuses)

    // Calculate growth trend
    if len(activities) >= 4 {
        recentWeeks := activities[:2]
        olderWeeks := activities[len(activities)-2:]

        recentAvg := (recentWeeks[0].Statuses + recentWeeks[1].Statuses) / 2
        olderAvg := (olderWeeks[0].Statuses + olderWeeks[1].Statuses) / 2

        if recentAvg > olderAvg {
            growth := float64(recentAvg-olderAvg) / float64(olderAvg) * 100
            fmt.Printf("\nGrowth trend: +%.1f%% (increasing activity)\n", growth)
        } else if recentAvg < olderAvg {
            decline := float64(olderAvg-recentAvg) / float64(olderAvg) * 100
            fmt.Printf("\nGrowth trend: -%.1f%% (declining activity)\n", decline)
        } else {
            fmt.Println("\nGrowth trend: Stable")
        }
    }

    return nil
}

Example: Federation Network Analysis

func analyzeFederation(client *mastodon.Client) error {
    ctx := context.Background()

    peers, err := client.GetInstancePeers(ctx)
    if err != nil {
        return err
    }

    fmt.Printf("Federation Analysis\n")
    fmt.Println(strings.Repeat("=", 50))
    fmt.Printf("Total federated instances: %d\n\n", len(peers))

    // Analyze by TLD
    tldCount := make(map[string]int)
    for _, peer := range peers {
        parts := strings.Split(peer, ".")
        if len(parts) >= 2 {
            tld := parts[len(parts)-1]
            tldCount[tld]++
        }
    }

    // Sort by count
    type tldInfo struct {
        tld   string
        count int
    }
    var tlds []tldInfo
    for tld, count := range tldCount {
        tlds = append(tlds, tldInfo{tld, count})
    }
    sort.Slice(tlds, func(i, j int) bool {
        return tlds[i].count > tlds[j].count
    })

    fmt.Println("Top TLDs:")
    for i := 0; i < 10 && i < len(tlds); i++ {
        percentage := float64(tlds[i].count) / float64(len(peers)) * 100
        fmt.Printf("  .%-10s %4d instances (%.1f%%)\n",
            tlds[i].tld, tlds[i].count, percentage)
    }

    return nil
}

Example: Instance Comparison

type InstanceInfo struct {
    URI      string
    Users    int64
    Statuses int64
    Version  string
}

func compareInstances(client1, client2 *mastodon.Client) error {
    ctx := context.Background()

    inst1, err := client1.GetInstance(ctx)
    if err != nil {
        return err
    }

    inst2, err := client2.GetInstance(ctx)
    if err != nil {
        return err
    }

    fmt.Println("Instance Comparison")
    fmt.Println(strings.Repeat("=", 70))

    fmt.Printf("%-25s %-20s %-20s\n", "", inst1.URI, inst2.URI)
    fmt.Println(strings.Repeat("-", 70))

    if inst1.Stats != nil && inst2.Stats != nil {
        fmt.Printf("%-25s %-20d %-20d\n",
            "Users", inst1.Stats.UserCount, inst2.Stats.UserCount)
        fmt.Printf("%-25s %-20d %-20d\n",
            "Statuses", inst1.Stats.StatusCount, inst2.Stats.StatusCount)
        fmt.Printf("%-25s %-20d %-20d\n",
            "Federation", inst1.Stats.DomainCount, inst2.Stats.DomainCount)
    }

    fmt.Printf("%-25s %-20s %-20s\n", "Version", inst1.Version, inst2.Version)

    return nil
}

Example: Instance Health Check

func checkInstanceHealth(client *mastodon.Client) error {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    startTime := time.Now()
    instance, err := client.GetInstance(ctx)
    responseTime := time.Since(startTime)

    fmt.Println("Instance Health Check")
    fmt.Println(strings.Repeat("=", 50))

    if err != nil {
        fmt.Printf("❌ Instance unreachable: %v\n", err)
        return err
    }

    fmt.Printf("✓ Instance reachable\n")
    fmt.Printf("  Response time: %v\n", responseTime)
    fmt.Printf("  Version: %s\n", instance.Version)

    if instance.Stats != nil {
        fmt.Printf("  Active users: %d\n", instance.Stats.UserCount)
        fmt.Printf("  Total posts: %d\n", instance.Stats.StatusCount)
    }

    // Check activity
    activities, err := client.GetInstanceActivity(ctx)
    if err == nil && len(activities) > 0 {
        recentActivity := activities[0]
        if recentActivity.Statuses > 0 {
            fmt.Printf("✓ Recent activity detected\n")
            fmt.Printf("  Last week: %d posts, %d logins\n",
                recentActivity.Statuses, recentActivity.Logins)
        } else {
            fmt.Printf("⚠ Low recent activity\n")
        }
    }

    // Performance rating
    if responseTime < 500*time.Millisecond {
        fmt.Println("\n✓ Performance: Excellent")
    } else if responseTime < 2*time.Second {
        fmt.Println("\n✓ Performance: Good")
    } else {
        fmt.Println("\n⚠ Performance: Slow")
    }

    return nil
}

Example: Extract Configuration

func extractConfiguration(client *mastodon.Client) (map[string]interface{}, error) {
    ctx := context.Background()

    instance, err := client.GetInstance(ctx)
    if err != nil {
        return nil, err
    }

    config := make(map[string]interface{})

    if instance.Configuration != nil {
        if instance.Configuration.Statuses != nil {
            config["status_max_chars"] = (*instance.Configuration.Statuses)["max_characters"]
            config["status_max_media"] = (*instance.Configuration.Statuses)["max_media_attachments"]
        }

        if instance.Configuration.MediaAttachments != nil {
            config["image_size_limit"] = instance.Configuration.MediaAttachments["image_size_limit"]
            config["video_size_limit"] = instance.Configuration.MediaAttachments["video_size_limit"]
        }

        if instance.Configuration.Polls != nil {
            config["poll_max_options"] = (*instance.Configuration.Polls)["max_options"]
            config["poll_max_duration"] = (*instance.Configuration.Polls)["max_expiration"]
        }
    }

    return config, nil
}

Best Practices

1. Cache Instance Information

Instance data changes infrequently:

type InstanceCache struct {
    instance  *mastodon.Instance
    fetchedAt time.Time
    ttl       time.Duration
}

func (ic *InstanceCache) Get(client *mastodon.Client, ctx context.Context) (*mastodon.Instance, error) {
    if time.Since(ic.fetchedAt) < ic.ttl && ic.instance != nil {
        return ic.instance, nil
    }

    instance, err := client.GetInstance(ctx)
    if err != nil {
        return nil, err
    }

    ic.instance = instance
    ic.fetchedAt = time.Now()
    return instance, nil
}

2. Check Limits Before Operations

Verify limits before attempting operations:

config, _ := extractConfiguration(client)
if maxChars, ok := config["status_max_chars"].(float64); ok {
    if len(statusText) > int(maxChars) {
        return fmt.Errorf("status too long: max %d chars", int(maxChars))
    }
}

3. Handle Missing Configuration

Not all instances provide full configuration:

if instance.Configuration == nil {
    // Use sensible defaults
    maxChars = 500
} else {
    // Extract from config
}

4. Monitor Instance Health

Regularly check instance availability:

ticker := time.NewTicker(5 * time.Minute)
for range ticker.C {
    checkInstanceHealth(client)
}

5. Respect Rate Limits

Instance endpoints count toward rate limits:

// Cache results
cachedInstance, _ := getCachedInstance()

// Don't poll too frequently
time.Sleep(time.Minute)

Related Types

See also:

  • Accounts - For contact account information
  • Types - For common types